Reputation: 661
I am trying to write a script that will look through a set of folders and keep only the last 10 files. The files in each folder could be created daily, weekly or monthly. I need the script to keep the 10 most recent copies regardless of the creation date or modified date.
Using another post I created the script below that works but it doesnt keep 10 copies it keeps any file that isn't older than 10 days.
$ftppath = "C:\Reports"
Get-ChildItem $ftppath -recurse *_Report_*.zip -force|where {$_.lastwritetime -lt (get-date).adddays(-10)} |Remove-Item -force
Any idea on how I can tweak this to work? If I use the script below it works but only if I dont set -Recurse. If you use the -Recurse switch you get an error that I have listed below the 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.
Upvotes: 27
Views: 36064
Reputation: 41
How to call this GCI command in SQL server , was trying below code but returning error
declare @deleteoldtempxe nvarchar(1000)
set @deleteoldtempxe='powershell.exe gci '+''''+ 'I:\New folder\'+''''+' -Recurse| where{-not $_.PsIsContainer}| sort CreationTime -desc|
select -Skip 1| Remove-Item -Force'
select @deleteoldtempxe
EXEC master.dbo.xp_cmdshell @deleteoldtempxe
Upvotes: -2
Reputation: 178
@Andy: My rep is too low to comment so posting an answer. If you are getting strange results, it may be because you are looking in Windows Explorer which by default shows the Last Modified date instead of the Creation Date. To get results consistent with that shown in Windows Explorer, swap LastWriteTime for CreationTime like so: gci C:\temp\ -Recurse| where{-not $_.PsIsContainer}| sort LastWriteTime -desc | select -Skip 10| Remove-Item -Force
Upvotes: 4
Reputation: 52679
Updated
$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
}
Remove the -WhatIf
parameter to Remove-Item
when your ready to delete for real.
Upvotes: 8
Reputation: 24343
You can sort by CreationTime
descending and skip the first 10. If there are less than 10 files it will not remove any.
gci C:\temp\ -Recurse| where{-not $_.PsIsContainer}| sort CreationTime -desc|
select -Skip 10| Remove-Item -Force
Upvotes: 73