Löschen Sie Dateien, die älter als 15 Tage sind, mit PowerShell


186

Ich möchte nur die Dateien löschen, die vor mehr als 15 Tagen in einem bestimmten Ordner erstellt wurden. Wie kann ich das mit PowerShell machen?


5
Die meisten Antworten verwenden CreationTime, werden jedoch beim Kopieren einer Datei zurückgesetzt, sodass Sie möglicherweise nicht die gewünschten Ergebnisse erhalten. LastWriteTime entspricht dem "Änderungsdatum" im Windows Explorer.
Roland Schaer

Antworten:


308

Mit den gegebenen Antworten werden nur Dateien gelöscht (was zugegebenermaßen im Titel dieses Beitrags steht). Hier ist jedoch ein Code, der zuerst alle Dateien löscht, die älter als 15 Tage sind, und dann alle verbleibenden leeren Verzeichnisse rekursiv löscht hinter. Mein Code verwendet auch die -ForceOption, um versteckte und schreibgeschützte Dateien zu löschen. Auch ich wählte nicht Aliase zu verwenden , da die OP neu in Powershell ist und kann nicht verstehen , was gci, ?, %etc. ist.

$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

Und wenn Sie sehen möchten, welche Dateien / Ordner gelöscht werden, bevor Sie sie tatsächlich löschen, können Sie den -WhatIfSchalter einfach zum Remove-ItemCmdlet-Aufruf am Ende beider Zeilen hinzufügen .

Der hier gezeigte Code ist PowerShell v2.0-kompatibel, aber ich zeige diesen Code und den schnelleren PowerShell v3.0-Code auch als praktische wiederverwendbare Funktionen in meinem Blog .


22
Vielen Dank, dass Sie keinen Alias ​​verwenden. Für jemanden, der neu in Powershell ist und diesen Beitrag über eine Google-Suche gefunden hat, halte ich Ihre Antwort für die beste.
Geoff Dawdy

1
Ich habe den Vorschlag von @ deaddog ausprobiert. Unabhängig davon, ob ich -15 oder -35 mit unterschiedlichen Dateierstellungsdaten für Monate (oder in letzter Zeit) angegeben habe, wird der gesamte Inhalt des Verzeichnisses gelöscht.
Michele

6
Wenn möglicherweise Dateien verwendet werden, sollten Sie dem Befehl RemoveItem auch "-ErrorAction SilentlyContinue" hinzufügen.
Kevin Owen

17
Vielen Dank! Ich benutze $ _. LastwriteTime anstelle von $ _. CreationTime
Lauri Lubi

2
Der zweite Befehl in diesem Skript erhält immer die Fehlermeldung, dass Get-ChildItem keinen Teil des Pfads finden kann. Es wird ein Verzeichnis nicht gefunden Ausnahme. Die leeren Ordner werden jedoch problemlos gelöscht. Ich bin mir nicht sicher, warum trotz der Arbeit ein Fehler auftritt.
Nathan McKaskle

51

einfach (PowerShell V5)

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

16

Eine andere Möglichkeit besteht darin, 15 Tage vom aktuellen Datum abzuziehen und mit CreationTimediesem Wert zu vergleichen :

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

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

13

Grundsätzlich iterieren Sie über Dateien unter dem angegebenen Pfad, subtrahieren die CreationTimevon jeder gefundenen Datei von der aktuellen Zeit und vergleichen sie mit der DaysEigenschaft des Ergebnisses. Der -WhatIfSchalter teilt Ihnen mit, was passieren wird, ohne die Dateien tatsächlich zu löschen (welche Dateien werden gelöscht). Entfernen Sie den Schalter, um die Dateien tatsächlich zu löschen:

$old = 15
$now = Get-Date

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

8

Versuche dies:

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

Ich glaube, der letzte -recurseist einer zu viel, nein? Die Verzeichnisliste ist rekursiv, das Löschen des Elements sollte nicht mit Kindern erfolgen, oder?
Joost

Wenn das Verzeichnis, mit dem Sie arbeiten, zwei Verzeichnisse tief ist, ist eine zweite Wiederholung erforderlich.
Bryan S.

5

Das Skript von Esperento57 funktioniert in älteren PowerShell-Versionen nicht. Dieses Beispiel macht:

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
Ich habe meine Antwort aktualisiert, um Verzeichnisse jetzt auszuschließen, danke.
KERR

3

Eine andere Alternative (15. wird automatisch in [Zeitspanne] eingegeben):

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

Dadurch werden alte Ordner und deren Inhalt gelöscht.


0

Wenn Sie Probleme mit den obigen Beispielen auf einer Windows - 10 - Box haben, versuchen Sie ersetzen .CreationTimemit .LastwriteTime. Das hat bei mir funktioniert.

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

LastwriteTimeist nicht dasselbe wie CreationTime, LastwriteTimewird jedes Mal aktualisiert, wenn die Datei geändert wird.
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"
    }
}

Außerdem wird die else- Anweisung niemals erreicht , da sie, wenn sie $Filesleer ist, die foreach- Anweisung nicht eingibt . Sie sollten das foreach in die if- Anweisung einfügen .
Dieter

@mati tatsächlich kann es die else-Anweisung erreichen. Wir haben eine ähnliche for-Schleife basierend auf einer Dateiliste und sie tritt regelmäßig in die for-Schleife mit der Variablen $ File als null ein
BeowulfNode42

Ich vermute, ich bin hier nur auf dasselbe Skript gestoßen. networknet.nl/apps/wp/published/…
Shawson
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.