Eliminar archivos anteriores a 15 días con PowerShell

186

Me gustaría eliminar solo los archivos que se crearon hace más de 15 días en una carpeta en particular. ¿Cómo podría hacer esto usando PowerShell?

usuario2470170
fuente
55
La mayoría de las respuestas usan CreationTime, sin embargo, se restablece cuando se copia un archivo, por lo que es posible que no obtenga los resultados que desea. LastWriteTime es lo que corresponde a la "Fecha de modificación" en el Explorador de Windows.
Roland Schaer

Respuestas:

308

Las respuestas dadas solo eliminarán archivos (lo que sin duda es lo que está en el título de esta publicación), pero aquí hay un código que primero eliminará todos los archivos anteriores a 15 días, y luego eliminará recursivamente cualquier directorio vacío que pueda haber quedado. detrás. Mi código también usa la -Forceopción de eliminar archivos ocultos y de solo lectura. También, he optado por no utilizar alias como el PO es nuevo para PowerShell y puede que no entienda lo que gci, ?, %, etc son.

$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

Y, por supuesto, si desea ver qué archivos / carpetas se eliminarán antes de eliminarlos, puede agregar el -WhatIfinterruptor a la Remove-Itemllamada al cmdlet al final de ambas líneas.

El código que se muestra aquí es compatible con PowerShell v2.0, pero también muestro este código y el código más rápido de PowerShell v3.0 como prácticas funciones reutilizables en mi blog .

perro mortal
fuente
22
Gracias por no usar alias. Para alguien que es nuevo en powershell y encontró esta publicación a través de una búsqueda en Google, considero que su respuesta es la mejor.
Geoff Dawdy
1
Intenté la sugerencia de @ deadlydog y no importa si especifico -15 o -35 con diferentes fechas de creación de archivos que se remontan a meses (o recientes), está eliminando todo el contenido del directorio.
Michele
66
Si los archivos pueden estar en uso, también vale la pena agregar "-ErrorAction SilentlyContinue" al comando RemoveItem.
Kevin Owen
17
¡Gracias! Yo uso $ _. LastwriteTime en lugar de $ _. CreationTime
Lauri Lubi
2
El segundo comando en ese script siempre recibe un error que Get-ChildItem no puede encontrar parte de la ruta. Obtiene una excepción de directorio no encontrado. Sin embargo, elimina las carpetas vacías sin ningún problema. No estoy seguro de por qué recibe un error a pesar de funcionar.
Nathan McKaskle
51

simplemente (PowerShell V5)

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

Otra forma es restar 15 días de la fecha actual y comparar CreationTimecon ese valor:

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

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

Básicamente, itera sobre los archivos bajo la ruta dada, resta el CreationTimede cada archivo encontrado de la hora actual y compara con la Dayspropiedad del resultado. El -WhatIfinterruptor le dirá lo que sucederá sin eliminar realmente los archivos (qué archivos se eliminarán), elimine el interruptor para eliminar realmente los archivos:

$old = 15
$now = Get-Date

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

Prueba esto:

dir C:\PURGE -recurse | 
where { ((get-date)-$_.creationTime).days -gt 15 } | 
remove-item -force
Roland Jansen
fuente
Creo que el último -recursees demasiado, ¿no? La lista de directorios es recursiva, la eliminación del elemento no debe ser con niños incluidos, ¿verdad?
Joost
Si el directorio con el que está trabajando tiene dos directorios de profundidad, se necesita una segunda repetición.
Bryan S.
5

El script de Esperento57 no funciona en versiones anteriores de PowerShell. Este ejemplo hace:

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
KERR
fuente
1
He actualizado mi respuesta para excluir directorios ahora, gracias.
KERR
3

Otra alternativa (15. se escribe en [intervalo de tiempo] automáticamente):

ls -file | where { (get-date) - $_.creationtime -gt 15. } | Remove-Item -Verbose
js2010
fuente
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

Esto eliminará las carpetas antiguas y su contenido.

Aigar
fuente
0

Si tiene problemas con los ejemplos anteriores en un cuadro de Windows 10, intente reemplazar .CreationTimecon .LastwriteTime. Esto funcionó para mí.

dir C:\locationOfFiles -ErrorAction SilentlyContinue | Where { ((Get-Date)-$_.LastWriteTime).days -gt 15 } | Remove-Item -Force
Jeff Blumenthal
fuente
LastwriteTimeno es lo mismo que CreationTime, LastwriteTimese actualiza cada vez que se modifica el archivo.
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"
    }
}
Ikruzzz
fuente
Además, nunca alcanzará la instrucción else , porque si $Filesestá vacía no ingresará la instrucción foreach . Debe colocar el foreach en la declaración if .
Dieter
@mati en realidad puede llegar a la declaración else. Tenemos un bucle for similar basado en una lista de archivos y regularmente ingresa el bucle for con la variable $ File como nula
BeowulfNode42
Supongo que sí, simplemente me topé con el mismo guión aquí; networknet.nl/apps/wp/published/…
Shawson