简体   繁体   English

使用PowerShell删除回收站中的旧文件

[英]Delete old files in recycle bin with powershell

Ok, I have a script I am writing in powershell that will delete old files in the recycle bin. 好的,我有一个我在powershell中编写的脚本,它将删除回收站中的旧文件。 I want it to delete all files from the recycle bin that were deleted more than 2 days ago. 我希望它删除回收站中超过2天前删除的所有文件。 I have done lots of research on this and have not found a suitable answer. 我对此做了大量研究,但没有找到合适的答案。

This is what I have so far(found the script online, i don't know much powershell): 这是我到目前为止(在线发现脚本,我不太了解powershell):

$Path = 'C' + ':\$Recycle.Bin'
Get-ChildItem $Path -Force -Recurse -ErrorAction SilentlyContinue |
#Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-3) } |
Remove-Item -Recurse -exclude *.ini -ErrorAction SilentlyContinue

It is working great with one exception, it checks the file parameter "LastWriteTime". 它有一个例外,它检查文件参数“LastWriteTime”。 That is awesome if the user deletes the file they same day they modify it. 如果用户在修改文件的同一天删除文件,那就太棒了。 Otherwise it fails. 否则它会失败。

How can I modify this code so that it will check when the file was deleted, not when it was written. 如何修改此代码,以便检查文件何时被删除,而不是在写入文件时。

-On a side note, if I run this script from an administrator account on Microsoft Server 2008 will it work for all users recycle bins or just mine? - 旁注,如果我从Microsoft Server 2008上的管理员帐户运行此脚本,它是否适用于所有用户回收箱或仅我的?


Answer: 回答:

the code that worked for me is: 对我有用的代码是:

$Shell = New-Object -ComObject Shell.Application
$Global:Recycler = $Shell.NameSpace(0xa)

foreach($item in $Recycler.Items())
{
    $DeletedDate = $Recycler.GetDetailsOf($item,2) -replace "\u200f|\u200e",""
    $dtDeletedDate = get-date $DeletedDate 
    If($dtDeletedDate -lt (Get-Date).AddDays(-3))
    {
        Remove-Item -Path $item.Path -Confirm:$false -Force -Recurse
    }#EndIF
}#EndForeach item

It works awesome for me, however 2 questions remain...How do I do this with multiple drives? 它对我来说很棒,但是还有两个问题......如何使用多个驱动器? and Will this apply to all users or just me? 这适用于所有用户还是仅适用于我?

WMF 5 includes the new "Clear-RecycleBin" cmdlet. WMF 5包含新的“Clear-RecycleBin”cmdlet。

PS > Clear-RecycleBin -DriveLetter C:\\ PS> Clear-RecycleBin -DriveLetter C:\\

These two lines will empty all the files recycle bin: 这两行将清空所有文件回收站:

$Recycler = (New-Object -ComObject Shell.Application).NameSpace(0xa)
$Recycler.items() | foreach { rm $_.path -force -recurse }

This article has answers to all your questions 本文可以解答您的所有问题

http://baldwin-ps.blogspot.be/2013/07/empty-recycle-bin-with-retention-time.html http://baldwin-ps.blogspot.be/2013/07/empty-recycle-bin-with-retention-time.html

Code for posterity: 子孙代码:

# ----------------------------------------------------------------------- 
#
#       Author    :   Baldwin D.
#       Description : Empty Recycle Bin with Retention (Logoff Script)
#     
# -----------------------------------------------------------------------

$Global:Collection = @()

$Shell = New-Object -ComObject Shell.Application
$Global:Recycler = $Shell.NameSpace(0xa)

$csvfile = "\\YourNetworkShare\RecycleBin.txt"
$LogFailed = "\\YourNetworkShare\RecycleBinFailed.txt"


function Get-recyclebin
{ 
    [CmdletBinding()]
    Param
    (
        $RetentionTime = "7",
        [Switch]$DeleteItems
    )

    $User = $env:USERNAME
    $Computer = $env:COMPUTERNAME
    $DateRun = Get-Date

    foreach($item in $Recycler.Items())
        {
        $DeletedDate = $Recycler.GetDetailsOf($item,2) -replace "\u200f|\u200e","" #Invisible Unicode Characters
        $DeletedDate_datetime = get-date $DeletedDate   
        [Int]$DeletedDays = (New-TimeSpan -Start $DeletedDate_datetime -End $(Get-Date)).Days

        If($DeletedDays -ge $RetentionTime)
            {
            $Size = $Recycler.GetDetailsOf($item,3)

            $SizeArray = $Size -split " "
            $Decimal = $SizeArray[0] -replace ",","."
            If ($SizeArray[1] -contains "bytes") { $Size = [int]$Decimal /1024 }
            If ($SizeArray[1] -contains "KB") { $Size = [int]$Decimal }
            If ($SizeArray[1] -contains "MB") { $Size = [int]$Decimal * 1024 }
            If ($SizeArray[1] -contains "GB") { $Size = [int]$Decimal *1024 *1024 }

       $Object = New-Object Psobject -Property @{
                Computer = $computer
                User = $User
                DateRun = $DateRun
                Name = $item.Name
                Type = $item.Type
                SizeKb = $Size
                Path = $item.path
                "Deleted Date" = $DeletedDate_datetime
                "Deleted Days" = $DeletedDays }

            $Object

                If ($DeleteItems)
                {
                    Remove-Item -Path $item.Path -Confirm:$false -Force -Recurse

                    if ($?)
                    {
                        $Global:Collection += @($object)
                    }
                    else
                    {
                        Add-Content -Path $LogFailed -Value $error[0]
                    }
                }#EndIf $DeleteItems
            }#EndIf($DeletedDays -ge $RetentionTime)
}#EndForeach item
}#EndFunction

Get-recyclebin -RetentionTime 7 #-DeleteItems #Remove the comment if you wish to actually delete the content


if (@($collection).count -gt "0")
{
$Collection = $Collection | Select-Object "Computer","User","DateRun","Name","Type","Path","SizeKb","Deleted Days","Deleted Date"
$CsvData = $Collection | ConvertTo-Csv -NoTypeInformation
$Null, $Data = $CsvData

Add-Content -Path $csvfile -Value $Data
}

[System.Runtime.Interopservices.Marshal]::ReleaseComObject($shell)

#ScriptEnd

This works well also as a script with the task scheduler. 这也可以作为任务调度程序的脚本。

Clear-RecycleBin -Force Clear-RecycleBin -Force

Had to do a bit of research on this myself, the recycle bin contains two files for every file deleted on every drive in win 10 (in win 7 files are as is so this script is too much and needs to be cut down, especially for powershell 2.0, win 8 untested), an info file created at time of deletion $I (perfect for ascertaining the date of deletion) and the original file $R, i found the com object method would ignore more files than i liked but on the up side had info i was interested in about the original file deleted, so after a bit of exploring i found a simple get-content of the info files included the original file location, after cleaning it up with a bit of regex and came up with this: 不得不自己做一些研究,回收站包含两个文件,用于win 10中每个驱动器上删除的每个文件(在win 7文件中是这样的,所以这个脚本太多了,需要减少,特别是对于powershell 2.0,win 8 untested),删除时创建的信息文件$ I(非常适合确定删除日期)和原始文件$ R,我发现com对象方法会忽略比我喜欢的更多文件但是在up side有信息我对删除的原始文件感兴趣,所以经过一些探索我发现一个简单的获取内容的信息文件包括原始文件位置,用一些正则表达式清理后,得出了这个:

# Refresh Desktop Ability
$definition = @'
    [System.Runtime.InteropServices.DllImport("Shell32.dll")] 
    private static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2);
    public static void Refresh() {
        SHChangeNotify(0x8000000, 0x1000, IntPtr.Zero, IntPtr.Zero);    
    }
'@
Add-Type -MemberDefinition $definition -Namespace WinAPI -Name Explorer

# Set Safe within deleted days and get physical drive letters
$ignoreDeletedWithinDays = 2
$drives = (gwmi -Class Win32_LogicalDisk | ? {$_.drivetype -eq 3}).deviceid

# Process discovered drives
$drives | % {$drive = $_
    gci -Path ($drive+'\$Recycle.Bin\*\$I*') -Recurse -Force | ? {($_.LastWriteTime -lt [datetime]::Now.AddDays(-$ignoreDeletedWithinDays)) -and ($_.name -like "`$*.*")} | % {

        # Just a few calcs
        $infoFile         = $_
        $originalFile     = gi ($drive+"\`$Recycle.Bin\*\`$R$($infoFile.Name.Substring(2))") -Force
        $originalLocation = [regex]::match([string](gc $infoFile.FullName -Force -Encoding Unicode),($drive+'[^<>:"/|?*]+\.[\w\-_\+]+')).Value
        $deletedDate      = $infoFile.LastWriteTime
        $sid              = $infoFile.FullName.split('\') | ? {$_ -like "S-1-5*"}
        $user             = try{(gpv "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\ProfileList\$($sid)" -Name ProfileImagePath).replace("$(gpv 'HKLM:\Software\Microsoft\Windows NT\CurrentVersion\ProfileList' -Name ProfilesDirectory)\",'')}catch{$Sid}

        #' Various info
        $originalLocation
        $deletedDate
        $user
        $sid
        $infoFile.Fullname
        ((gi $infoFile -force).length / 1mb).ToString('0.00MB')
        $originalFile.fullname
        ((gi $originalFile -force).length / 1mb).ToString('0.00MB')
        ""

        # Blow it all Away
        #ri $InfoFile -Recurse -Force -Confirm:$false -WhatIf
        #ri $OriginalFile -Recurse -Force -Confirm:$false- WhatIf
        # remove comment before two lines above and the '-WhatIf' statement to delete files
    }
}

# Refresh desktop icons
[WinAPI.Explorer]::Refresh()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM