【问题标题】:Delete old files in recycle bin with powershell使用powershell删除回收站中的旧文件
【发布时间】:2014-04-02 15:29:50
【问题描述】:

好的,我有一个我正在用 powershell 编写的脚本,它将删除回收站中的旧文件。我希望它从回收站中删除超过 2 天前删除的所有文件。我对此做了很多研究,但没有找到合适的答案。

这是我目前所拥有的(在网上找到了脚本,我不太了解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

它运行良好,但有一个例外,它检查文件参数“LastWriteTime”。如果用户在修改文件的同一天删除了文件,那就太棒了。否则失败。

如何修改此代码,以便它检查文件何时被删除,而不是何时被写入。

-附带说明,如果我从 Microsoft Server 2008 上的管理员帐户运行此脚本,它将适用于所有用户的回收站还是只适用于我的?


答案:

对我有用的代码是:

$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

它对我来说很棒,但是还有 2 个问题......如何使用多个驱动器执行此操作?这适用于所有用户还是仅适用于我?

【问题讨论】:

    标签: powershell recycle-bin


    【解决方案1】:

    WMF 5 包含新的“Clear-RecycleBin”cmdlet。

    PS> Clear-RecycleBin -DriveLetter C:\

    【讨论】:

      【解决方案2】:

      这两行将清空所有文件回收站:

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

      【讨论】:

      • 如果重要,请注意这不会刷新桌面上的回收站图标
      【解决方案3】:

      这篇文章回答了你所有的问题

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

      后人代码:

      # ----------------------------------------------------------------------- 
      #
      #       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
      

      【讨论】:

      • 我喜欢这个,这似乎是我想要的,但我很难从他的脚本中过滤出我想要的东西。我看到 $DeletedDate = $Recycler.GetDetailsOf($item,2) -replace "\u200f|\u200e","" 得到了我正在寻找的东西,但是 $Recycler 定义在哪里?
      • 脚本的第二行,$Global:Recycler 将其定义为全局变量。
      • 您能否将文章中的一些见解转移到您的答案中?我们不能假设链接会永远存在。
      • 好吧,这是一个愚蠢的错误。我在顶部查看的是他的脚本中的摘录,而不是底部的整个脚本。让代码工作得很好!但是,如何将相同的东西应用于不同的驱动器?我需要它为 E: 和 F: 做同样的事情。这也适用于所有用户还是仅适用于我?
      • 我没有那么多问题。我只是想要几行 PS 来清空所有驱动器上的回收站。
      【解决方案4】:

      必须自己对此进行一些研究,回收站包含两个文件,用于在 win 10 中每个驱动器上删除的每个文件(在 win 7 中文件是原样所以这个脚本太多了,需要减少, 特别是对于 powershell 2.0, win 8 untested), 删除时创建的信息文件 $I (非常适合确定删除日期) 和原始文件 $R, 我发现 com 对象方法会忽略比我喜欢的更多的文件但从好的方面来说,我对删除的原始文件感兴趣,所以经过一番探索后,我发现信息文件的简单获取内容包括原始文件位置,在用一些正则表达式和想出了这个:

      # 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()
      

      【讨论】:

      • 作为一个powershell新手,这个脚本在哪里运行?可以放入.bat文件吗?
      • 没问题。我发现代码可以从扩展名为 .ps1 的文件中运行。要运行,请右键单击该文件并单击“使用 PowerShell 运行”。
      【解决方案5】:

      这也适用于任务调度程序的脚本。

      清除-RecycleBin -Force

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-06
        • 1970-01-01
        • 2019-06-18
        • 2018-03-03
        • 2010-11-18
        相关资源
        最近更新 更多