Elimina i file più vecchi di 15 giorni usando PowerShell


186

Vorrei eliminare solo i file creati più di 15 giorni fa in una cartella specifica. Come potrei farlo usando PowerShell?


5
La maggior parte delle risposte utilizza CreationTime, tuttavia viene reimpostata quando un file viene copiato, pertanto potresti non ottenere i risultati desiderati. LastWriteTime è ciò che corrisponde alla "Data modificata" in Esplora risorse.
Roland Schaer,

Risposte:


308

Le risposte fornite elimineranno solo i file (che è certamente quello che è nel titolo di questo post), ma ecco un codice che eliminerà prima tutti i file più vecchi di 15 giorni, quindi eliminerà ricorsivamente tutte le directory vuote che potrebbero essere state lasciate dietro a. Il mio codice utilizza anche l' -Forceopzione per eliminare anche i file nascosti e di sola lettura. Inoltre, ho scelto di non utilizzare alias come il PO è nuovo a PowerShell e non può capire cosa gci, ?, %, ecc sono.

$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

E, naturalmente, se si desidera vedere quali file / cartelle verranno eliminati prima di eliminarli, è possibile aggiungere il -WhatIfpassaggio alla Remove-Itemchiamata del cmdlet alla fine di entrambe le linee.

Il codice mostrato qui è compatibile con PowerShell v2.0, ma mostro anche questo codice e il codice PowerShell v3.0 più veloce come utili funzioni riutilizzabili sul mio blog .


22
Grazie per non aver usato gli alias. Per chi è nuovo su PowerShell e ha trovato questo post tramite una ricerca su Google, ritengo che la tua risposta sia la migliore.
Geoff Dawdy,

1
Ho provato il suggerimento di @ deadlydog e non importa se specifico -15 o -35 con date di creazione dei file variabili risalenti a mesi (o recenti), sta eliminando l'intero contenuto della directory.
Michele,

6
Se i file possono essere in uso, vale anche la pena aggiungere "-ErrorAction SilentlyContinue" al comando RemoveItem.
Kevin Owen,

17
Grazie! Uso $ _. LastwriteTime invece di $ _. CreationTime
Lauri Lubi

2
Il secondo comando in quello script riceve sempre un errore che Get-ChildItem non riesce a trovare parte del percorso. Ottiene un'eccezione directory non trovata. Tuttavia elimina le cartelle vuote senza problemi. Non sono sicuro del motivo per cui si sta verificando un errore nonostante funzioni.
Nathan McKaskle,

51

semplicemente (PowerShell V5)

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

16

Un altro modo è sottrarre 15 giorni dalla data corrente e confrontarlo CreationTimecon quel valore:

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

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

13

Fondamentalmente, si esegue l'iterazione sui file nel percorso specificato, si sottrae il valore CreationTimedi ciascun file trovato dall'ora corrente e si confronta con la Daysproprietà del risultato. Lo -WhatIfswitch ti dirà cosa accadrà senza effettivamente eliminare i file (quali file verranno eliminati), rimuovi lo switch per eliminare effettivamente i file:

$old = 15
$now = Get-Date

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

8

Prova questo:

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

Credo che l'ultimo -recursesia uno di troppo, no? L'elenco dir è ricorsivo, la cancellazione dell'articolo non dovrebbe essere inclusa con i bambini, giusto?
Joost

Se la directory con cui stai lavorando ha due directory in profondità, è necessario un secondo richiamo.
Bryan S.

5

Lo script di Esperento57 non funziona nelle versioni precedenti di PowerShell. Questo esempio fa:

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
Ho aggiornato la mia risposta per escludere le directory ora, grazie.
KERR,

3

Un'altra alternativa (15. viene digitata automaticamente su [timespan]):

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

Questo eliminerà le vecchie cartelle e il suo contenuto.


0

Se riscontri problemi con gli esempi sopra riportati su una scatola di Windows 10, prova a sostituirlo .CreationTimecon .LastwriteTime. Questo ha funzionato per me.

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

LastwriteTimenon è lo stesso di CreationTime, LastwriteTimeviene aggiornato ogni volta che il file viene modificato.
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"
    }
}

Inoltre, non raggiungerà mai l' altro istruzione , perché se $Filesè vuota non inserirà l' istruzione foreach . Dovresti inserire la foreach nell'istruzione if .
Dieter,

@mati in realtà può raggiungere la dichiarazione else. Abbiamo un ciclo for simile simile basato su un elenco di file ed entra regolarmente nel ciclo for con la variabile $ File come null
BeowulfNode42

Immagino di sì, sono solo incappato nella stessa sceneggiatura qui; networknet.nl/apps/wp/published/…
Shawson
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.