2012-01-10 17 views
16

Estoy tratando de escribir un script que busque en un conjunto de carpetas y guarde solo los últimos 10 archivos. Los archivos en cada carpeta se pueden crear diariamente, semanalmente o mensualmente. Necesito la secuencia de comandos para mantener las 10 copias más recientes independientemente de la fecha de creación o la fecha de modificación.Mantener x número de archivos y eliminar todos los demás - Powershell

Usando otra publicación creé la siguiente secuencia de comandos que funciona, pero no mantiene 10 copias, guarda cualquier archivo que no tenga más de 10 días.

$ftppath = "C:\Reports" 
Get-ChildItem $ftppath -recurse *_Report_*.zip -force|where {$_.lastwritetime -lt (get-date).adddays(-10)} |Remove-Item -force 

¿Alguna idea sobre cómo puedo ajustar esto para trabajar? Si utilizo el script a continuación, funciona, pero solo si no configuro -Recurse. Si usas el parámetro -Recurse, obtienes un error que he enumerado debajo del script.

# Keeps latest 10 files from a directory based on Creation Time 

#Declaration variables 
$path = "C:\Reports"        # For example $path= C:\log\*.tmp 
$total= (ls $path).count - 10 # Change number 5 to whatever number of objects you want to keep 
# Script 
ls $path |sort-object -Property {$_.CreationTime} | Select-Object -first $total | Remove-Item -force 

Error: Select-Object : Cannot validate argument on parameter 'First'. The -7 argument is less than the minimum allowed range of 0. Supply an argument that is greater than 0 and then try the command again.

Respuesta

32

Puede ordenar por CreationTime descendiendo y saltearse el primero 10. Si hay menos de 10 archivos, no se eliminará ninguno.

gci C:\temp\ -Recurse| where{-not $_.PsIsContainer}| sort CreationTime -desc| 
    select -Skip 10| Remove-Item -Force 
+1

Ah '-Skip'. Agradable y conciso :-) +1 –

+0

Estaba probando esto y obtuve algunos resultados extraños, no estoy seguro de lo que estaba pasando allí ... Volví a probarlo y funciona como esperaba. Buen trazador de líneas 1. –

+0

@Andy - Sí, probé tu código para crear archivos, y la segunda vez que lo ejecuté, The creationTime no se actualizó para todos los archivos. Aunque no sé exactamente por qué: -/ – Rynant

8

Actualizado

$path = "C:\TestDir" 

# Create 12 test files, 1 second after each other 
1..12 | % { 
    Remove-Item -Path "$path\$_.txt" -ea SilentlyContinue 
    $_ | Out-File "$path\$_.txt" 
    Start-Sleep -Seconds 1 
} 

$files = Get-ChildItem -Path $path -Recurse | Where-Object {-not $_.PsIsContainer} 
$keep = 10 
if ($files.Count -gt $keep) { 
    $files | Sort-Object CreationTime | Select-Object -First ($files.Count - $keep) | Remove-Item -Force -WhatIf 
} 

eliminar el parámetro -WhatIf a Remove-Item cuando su listo para eliminar de verdad.

+0

¿No elimina esto todos los archivos? – Rynant

+0

Ah, gracias, sí, la versión anterior sería de. Ayuda a probar más ;-) Actualicé con una versión probada de trabajo. –

+0

Gracias por la ayuda. Esto ahora se está ejecutando como se esperaba. Gracias de nuevo. – mpowmap

1

@Andy: Mi representante es demasiado bajo para comentar y publicar una respuesta. Si obtiene resultados extraños, puede deberse a que está buscando en el Explorador de Windows, que de forma predeterminada muestra la fecha de la Última modificación en lugar de la Fecha de creación. Para obtener resultados consistentes con los que se muestran en el Explorador de Windows, cambie LastWriteTime por CreationTime de la siguiente manera: gci C: \ temp \ -Recurse | donde {-not $ _. PsIsContainer} | ordenar LastWriteTime -desc | seleccione -Skip 10 | Remove-Item -Force

Cuestiones relacionadas