Contents

Script Dumpster: Keep last X amount of files or Y amount of days


Contents

Ever had the need to remove all but the last X amount of copies of a back-up?

And I’m not talking about the copies from the last 2 days, because this can cause issues if the files aren’t created daily [in case of a weekend], in case a back-up has failed in the meantime or if multiple back-up copies have been made in one day.

While at first I was always playing around with the simple solution by checking file age, I ran into a more elegant solution I’d like to share with you.

Both solutions are essentially one liners after the defining of variables, but I’ve split up the code a bit for readability. Also both codes still have the

1
-WhatIf

switch added, so that you don’t accidentally run this in production and remove the incorrect files. Please change accordingly!

Keep Y amount of days

This example is used to keep the files from the last 4 days in order to make sure I keep the Friday and Monday file available [no separate back-ups are made over the weekend]. This solution writes the deleted file to a separate log file so you can see which files were [perhaps accidentally] deleted. Big downsides to this solution are:

  • While I still have the files for Friday and Monday, it means during weekdays I’ll have 4 copies of the back-up file, which can flood your disk.
  • If I make multiple back-ups on 1 day, it will still retain those files, as they simple need to have a maximum age before they’re removed.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
$Path = 'D:\Backup'
$FileType = '*.bak'
$Age = 4
$DateNow = Get-Date -Format ddMMyyyy
$DateThen = (Get-Date).AddDays(-$Age)

Get-ChildItem -Path $Path -Filter $FileType |
   Where-Object {$_.CreationTime -lt $DateThen} |
   foreach {
      "Deleting file $($_.FullName) on $DateNow" ;
      Remove-Item $_.FullName -WhatIf} |
   Out-File "$Path\$DateNow.txt" -Force

Keep X amount of files

Personally this is my preferred and more elegant solution in order to keep only the last X amount of back-up files.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
$Path = 'D:\Backup'
$FileType = '*.bak'
$KeepAmount = 2
$DateNow = Get-Date -Format ddMMyyyy

Get-ChildItem -Path $Path -Filter $FileType |
   Sort-Object CreationTime -Descending |
   Select-Object -Skip $KeepAmount |
   foreach {
      "Deleting file $($_.FullName) on $DateNow" ;
      Remove-Item $_.FullName -WhatIf} |
Out-File "$Path\$DateNow.txt" -Force

While this can create an issue when you make multiple back-ups on a single day, it’s would be the preferred solution in most cases.

Happy Scripting! 🙂