Удалить старые файлы в корзине с помощью powershell

Хорошо, у меня есть скрипт, который я пишу в 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 вопроса ... Как мне это сделать с несколькими дисками? и Будет ли это применяться ко всем пользователям или только ко мне?


person Dead_Jester    schedule 02.04.2014    source источник


Ответы (5)


В этой статье есть ответы на все ваши вопросы

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
person Raf    schedule 02.04.2014
comment
Мне это нравится, это, кажется, делает то, что я хочу, но мне трудно отфильтровать то, что я хочу от его сценария. Я вижу, что $DeletedDate = $Recycler.GetDetailsOf($item,2) -replace "\u200f|\u200e","" получает то, что я ищу, но где определяется $Recycler? - person Dead_Jester; 02.04.2014
comment
Вторая строка скрипта, $Global:Recycler, определяет его как глобальную переменную. - person TheMadTechnician; 02.04.2014
comment
Не могли бы вы перенести некоторые идеи из статьи в свой ответ? Мы не можем предположить, что ссылка будет жить вечно. - person Anthony Neace; 02.04.2014
comment
Хорошо, это была глупая ошибка. Я смотрел отрывок из его сценария вверху, а не весь сценарий внизу. Получил код работает отлично! Как мне применить то же самое к разным дискам? Мне нужно, чтобы он делал то же самое для E: и F:. Также это относится ко всем пользователям или только ко мне? - person Dead_Jester; 02.04.2014
comment
У меня не так много вопросов. Мне просто нужно несколько строк PS, чтобы очистить корзину на всех дисках. - person AndreiM; 10.11.2015

WMF 5 включает новый командлет Clear-RecycleBin.

PS > Clear-RecycleBin -DriveLetter C:\

person N P    schedule 09.10.2016

Эти две строки очистят всю корзину файлов:

$Recycler = (New-Object -ComObject Shell.Application).NameSpace(0xa)
$Recycler.items() | foreach { rm $_.path -force -recurse }
person cmcginty    schedule 12.06.2015
comment
Если это имеет значение, обратите внимание, что это не обновит значок корзины на рабочем столе. - person xdhmoore; 23.12.2016

Пришлось немного изучить этот вопрос, корзина содержит два файла для каждого файла, удаленного на каждом диске в win 10 (в win 7 файлы такие, как есть, поэтому этот скрипт слишком много и его нужно сократить, особенно для powershell 2.0, win 8 не тестировалась), информационный файл, созданный во время удаления $I (идеально подходит для определения даты удаления) и исходный файл $R, я обнаружил, что метод объекта com будет игнорировать больше файлов, чем мне хотелось, но на вверху была интересующая меня информация об удалении исходного файла, поэтому после небольшого изучения я нашел простой get-content информационных файлов, включающий исходное местоположение файла, после очистки его с помощью небольшого количества регулярных выражений и придумал это:

# 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()
person James Burleigh    schedule 08.05.2018
comment
Как новичок в powershell, где запускается этот скрипт? Можно ли его поместить в .bat файл? - person WonderWorker; 27.06.2018
comment
Без проблем. Я узнал, что код можно запустить из файла с расширением .ps1. Для запуска щелкните файл правой кнопкой мыши и выберите «Выполнить с помощью PowerShell». - person WonderWorker; 27.06.2018

Это также хорошо работает в качестве сценария с планировщиком задач.

Clear-RecycleBin-Force

person LetzerWille    schedule 31.01.2018