0
votes
Get-ChildItem –Path  “H:\backups” –Recurse | Where-Object{$_.CreationTime –lt (Get-Date).AddDays(-4)} | Remove-Item 

I have this Script that can delete files older than 4 days. However I want to control that it should delete X number of files+folder 4 days old and also want to get the logs so that I see it later. Below is the script, Is it fine?

$Now = Get-Date
$Days = "4"
$TargetFolder = "H:\backups"
$LastWrite = $Now.AddDays(-$days)
$Files = get-childitem $TargetFolder -include *.*  -recurse -force
     Where {$_.CreationTime -le "$LastWrite"} 
    foreach ($i in Get-ChildItem $TargetFolder -recurse)
{
    if ($i.CreationTime -lt ($(Get-Date).AddDays(-10)))
    {
        Remove-Item $Files -recurse -force
    }
}
    Write-Output $Files >> c:\delete.log
2
Is it fine - are you asking if it will work? You can find this out for yourself by testing the script on a test directory with test files.Bill_Stewart
Didn't work do you have any ? how to get output of what files got deleted on below script. Get-ChildItem –Path “H:\backups” –Recurse | Where-Object{$_.CreationTime –lt (Get-Date).AddDays(-4)} | Remove-Itemjacksh
Output the file's name before deleting it.Bill_Stewart

2 Answers

0
votes

I believe this would work, allowing you to pass a path and a number of days you'd want to keep as parameters:

function RemoveOld($path, $filefilter, $daystokeep)
{
    $findfiles = @(Get-ChildItem -Path $path -Include $filefilter)
    $toRemove = $findfiles | Where-Object CreationTime -le (Get-Date).AddDays(-$daystokeep)
    $toRemove >> c:\temp\delete.log
    $toRemove | Remove-Item
}

RemoveOld -path "H:\backups\*" -filefilter "*" -daystokeep 4

May I also suggest, rather than deleting files older than a given time-frame, remove the files older than the most recent X number of files. In this way you'd always keep some number of files and not end up in a situation where all your files are deleted if the backup somehow fails to run for several days. It could be an option depending on how your folder structure is set up (modify the filefilter parameter so you don't delete more than desired).

function RemoveOlder($path, $filefilter, $filestokeep)
{
    $findfiles = @(Get-ChildItem -Path $path -Include $filefilter)
    if ($findfiles.Count -gt $filestokeep) {
        $findfiles | Sort-Object LastWriteTime -Descending | Select-Object -Last ($findfiles.Count - $filestokeep) | Remove-Item
    }
}

RemoveOlder -path "H:\backups\*" -filefilter "*" -filestokeep 4
0
votes

On your original command, add this:

 -Verbose 4>&1 | Out-File -FilePath D:\delete.log -Append

4 is Verbose output so this is redirecting Verbose to stdout 1, then redirecting both to a log file. The final command would be:

Get-ChildItem –Path  “H:\backups” –Recurse `
 | Where-Object{$_.CreationTime –lt (Get-Date).AddDays(-4)} `
 | Remove-Item -Verbose 4>&1 | Out-File -FilePath C:\delete.log -Append

Update: If you want the command to run without interaction and continue on errors etc. for a scheduled task, add additional parameters to Remove-Item:

Get-ChildItem –Path  “H:\backups” –Recurse `
   | Where-Object{$_.CreationTime –lt (Get-Date).AddDays(-4)} `
   | Remove-Item -Verbose -Force -ErrorAction SilentlyContinue -Confirm:$false 4>&1 `
   | Out-File -FilePath C:\delete.log -Append