Usuń pliki starsze niż 15 dni za pomocą PowerShell


186

Chciałbym usunąć tylko pliki, które zostały utworzone ponad 15 dni temu w określonym folderze. Jak mogę to zrobić za pomocą programu PowerShell?


5
Większość odpowiedzi używa CreationTime, jednak resetuje się, gdy plik jest kopiowany, więc możesz nie uzyskać pożądanych wyników. LastWriteTime odpowiada terminowi „Data modyfikacji” w Eksploratorze Windows.
— Roland Schaer

Odpowiedzi:


308

Podane odpowiedzi usuwają tylko pliki (co wprawdzie jest w tytule tego postu), ale oto kod, który najpierw usunie wszystkie pliki starsze niż 15 dni, a następnie rekurencyjnie usunie wszystkie puste katalogi, które mogły pozostać za. Mój kod wykorzystuje również -Forceopcję usuwania plików ukrytych i tylko do odczytu. Również wybrałem, aby nie używać aliasów jako OP jest nowy PowerShell i nie może zrozumieć, co gci, ?, %, itd. Są.

$limit = (Get-Date).AddDays(-15)
$path = "C:\Some\Path"

# Delete files older than the $limit.
Get-ChildItem -Path $path -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force

# Delete any empty directories left behind after deleting the old files.
Get-ChildItem -Path $path -Recurse -Force | Where-Object { $_.PSIsContainer -and (Get-ChildItem -Path $_.FullName -Recurse -Force | Where-Object { !$_.PSIsContainer }) -eq $null } | Remove-Item -Force -Recurse

I oczywiście, jeśli chcesz zobaczyć, które pliki / foldery zostaną usunięte przed ich faktycznym usunięciem, możesz po prostu dodać -WhatIfprzełącznik doRemove-Item wywołania polecenia cmdlet na końcu obu wierszy.

Kod pokazany tutaj jest zgodny z PowerShell v2.0, ale pokazuję ten kod i szybszy kod PowerShell v3.0 jako przydatne funkcje wielokrotnego użytku na moim blogu .


22
Dziękujemy za nieużywanie aliasu. Dla kogoś, kto jest nowy w PowerShell i znalazł ten post za pomocą wyszukiwarki Google, uważam twoją odpowiedź za najlepszą.
— Geoff Dawdy

1
Wypróbowałem sugestię @ deadlydog i bez względu na to, czy podam -15 lub -35 ze zmiennymi datami tworzenia plików w poprzednich miesiącach (lub ostatnich), usuwa całą zawartość katalogu.
— Michele

6
Jeśli pliki mogą być w użyciu, warto również dodać „-ErrorAction SilentlyContinue” do polecenia RemoveItem.
— Kevin Owen,

17
Dzięki! Używam $ _. LastwriteTime zamiast $ _. CreationTime
— Lauri Lubi

2
Drugie polecenie w tym skrypcie zawsze powoduje błąd, że Get-ChildItem nie może znaleźć części ścieżki. Otrzymuje wyjątek nie znaleziony katalog. Jednak bez problemu usuwa puste foldery. Nie jestem pewien, dlaczego mimo działania pojawia się błąd.
— Nathan McKaskle

51

po prostu (PowerShell V5)

Get-ChildItem "C:\temp" -Recurse -File | Where CreationTime -lt  (Get-Date).AddDays(-15)  | Remove-Item -Force

16

Innym sposobem jest odjęcie 15 dni od bieżącej daty i porównanie CreationTimez tą wartością:

$root  = 'C:\root\folder'
$limit = (Get-Date).AddDays(-15)

Get-ChildItem $root -Recurse | ? {
  -not $_.PSIsContainer -and $_.CreationTime -lt $limit
} | Remove-Item

13

Zasadniczo iterujesz pliki pod daną ścieżką, odejmujesz CreationTimekażdy znaleziony plik od bieżącego czasu i porównujesz z Dayswłaściwością wyniku. -WhatIfPrzełącznik powie, co się stanie, bez faktycznie usuwanie plików (które zostaną usunięte pliki), usunąć przełącznik faktycznie usunąć pliki:

$old = 15
$now = Get-Date

Get-ChildItem $path -Recurse |
Where-Object {-not $_.PSIsContainer -and $now.Subtract($_.CreationTime).Days -gt $old } |
Remove-Item -WhatIf

8

Spróbuj tego:

dir C:\PURGE -recurse | 
where { ((get-date)-$_.creationTime).days -gt 15 } | 
remove-item -force

Uważam, że ostatni -recurseto za dużo, nie? Lista reżimów jest rekurencyjna, usunięcie elementu nie powinno dotyczyć dzieci, prawda?
— Joost

Jeśli katalog, z którym pracujesz, ma głębokość dwóch katalogów, potrzebna jest druga sekwencja.
— Bryan S.,

5

Skrypt Esperento57 nie działa w starszych wersjach PowerShell. Ten przykład:

Get-ChildItem -Path "C:\temp" -Recurse -force -ErrorAction SilentlyContinue | where {($_.LastwriteTime -lt  (Get-Date).AddDays(-15) ) -and (! $_.PSIsContainer)} | select name| Remove-Item -Verbose -Force -Recurse -ErrorAction SilentlyContinue

1
Zaktualizowałem swoją odpowiedź, aby wykluczyć katalogi teraz, dzięki.
— KERR

3

Inna alternatywa (15. zostaje automatycznie wpisany na [przedział czasowy]):

ls -file | where { (get-date) - $_.creationtime -gt 15. } | Remove-Item -Verbose

1
$limit = (Get-Date).AddDays(-15)
$path = "C:\Some\Path"

# Delete files older than the $limit.
Get-ChildItem -Path $path -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force -Recurse

Spowoduje to usunięcie starych folderów i ich zawartości.


0

Jeśli występują problemy z powyższych przykładów na polu Windows 10, spróbuj wymienić .CreationTimez .LastwriteTime. To zadziałało dla mnie.

dir C:\locationOfFiles -ErrorAction SilentlyContinue | Where { ((Get-Date)-$_.LastWriteTime).days -gt 15 } | Remove-Item -Force

LastwriteTimeto nie to samo co CreationTime, LastwriteTimeaktualizuje się za każdym razem, gdy plik jest modyfikowany.
— MisterSmith

-1
#----- Define parameters -----#
#----- Get current date ----#
$Now = Get-Date
$Days = "15" #----- define amount of days ----#
$Targetfolder = "C:\Logs" #----- define folder where files are located ----#
$Extension = "*.log" #----- define extension ----#
$Lastwrite = $Now.AddDays(-$Days)

#----- Get files based on lastwrite filter and specified folder ---#
$Files = Get-Children $Targetfolder -include $Extension -Recurse | where {$_.LastwriteTime -le "$Lastwrite"}

foreach ($File in $Files)
{
    if ($File -ne $Null)
    {
        write-host "Deleting File $File" backgroundcolor "DarkRed"
        Remove-item $File.Fullname | out-null
    }
    else
        write-host "No more files to delete" -forgroundcolor "Green"
    }
}

Ponadto nigdy nie osiągnie instrukcji else , ponieważ jeśli $Filesjest pusta, nie wejdzie do instrukcji foreach . Powinieneś umieścić foreach w instrukcji if .
— Dieter

@ mati faktycznie może dotrzeć do instrukcji else. Mamy podobną pętlę for opartą na liście plików i regularnie wchodzi ona do pętli ze zmienną $ File jako null
— BeowulfNode42

Chyba tak - natknąłem się tutaj na ten sam skrypt; networknet.nl/apps/wp/published/…
— Shawson
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.