Prune-Backups.ps1: Prune Backup Files with PowerShell
Do you have a program that dumps daily backups into a folder which would eat up your disk? Do you want to automatically delete some of those files but keep backups of certain ages? This is just the case for which I wrote Prune-Backups.ps1
param (
[ string ] $ Path = ( Get-Location ) ,
[ int ] $ Hours = 0 ,
[ int ] $ Days = 0 ,
[ int ] $ Weeks = 0 ,
[ int ] $ Months = 0 ,
[ int ] $ Years = 0 ,
[ switch ] $ Summary = $ true,
[ switch ] $ WhatIf
)
$ now = Get-Date
$ hourlyDates = 0 ..- $ Hours | % { $ now.addHours ( $ _) }
$ dailyDates = 0 ..- $ Days | % { $ now.addDays ( $ _) }
$ weeklyDates = 0 ..- $ Weeks | % { $ now.addDays ( $ _* 7 ) }
$ monthlyDates = 0 ..- $ Months | % { $ now.addMonths ( $ _) }
$ yearlyDates = 0 ..- $ Years | % { $ now.addYears ( $ _) }
$ datesToKeep = @ ( ) + $ hourlyDates + $ dailyDates + $ monthlyDates + $ weeklyDates + $ yearlyDates | Sort - Unique
$ files = Get-ChildItem - Path $ Path - File
function Get-ClosestFile {
param (
[ datetime ] $ referenceDate,
[ array ] $ files
)
foreach ( $ file in $ files) {
$ diff = ( New-TimeSpan - Start $ file.LastWriteTime - End $ referenceDate) .Duration( )
if ( ! $ smallestDiff -or $ diff -lt $ smallestDiff) {
$ smallestDiff = $ diff
$ closestFile = $ file
}
}
return $ closestFile
}
$ filesToKeep = @ ( )
foreach ( $ date in $ datesToKeep) {
$ file = Get-ClosestFile - referenceDate $ date - files $ files
if ( $ file -ne $ null -and $ filesToKeep -notcontains $ file) {
$ filesToKeep += $ file
}
}
$ filesToKeep = $ filesToKeep | Sort LastWriteTime - Unique
$ lengthDeleted = 0
$ files | ? { $ _ -notin $ filesToKeep} | % {
$ lengthDeleted += $ _.Length
if ( $ WhatIf) {
Write-Output " WhatIf: Deleting file '$ ( $ _.FullName ) ' [$ ( $ _.LastWriteTime ) ]"
} else {
Write-Output " Deleting file '$ ( $ _.FullName ) ' [$ ( $ _.LastWriteTime ) ]"
Remove-Item $ _ - Force
}
}
Write-Output " Operation complete."
if ( $ summary) {
Write-Output " Retained files:"
$ filesToKeep | % { " [$ ( $ _.LastWriteTime ) ] $ ( $ _.FullName ) " }
$ deleted = [ math ] ::round( $ lengthDeleted/ 1 Mb , 3 )
$ remaining = [ math ] ::round( ( $ filesToKeep | Measure - Sum Length) .Sum/ 1 Mb , 3 )
$ percentDeleted = [ math ] ::round( $ deleted/ ( $ remaining+ $ deleted) , 3 ) * 100
Write-Output " Removed $ ( $ deleted) MiB ($ ( $ percentDeleted) %), kept $ ( $ remaining) MiB"
}
Letβs say you want to keep a backup from every day of the last week, as well as copies from 2, 3, and 4 weeks ago, 1, 2, and 3 months ago, 1 and 2 years ago. You can try it from the folder in question with the -WhatIf
flag:
./ Prune- Backups.ps1 - Days 7 - Weeks 4 - Months 3 - Years 2 - WhatIf
It will report back which files would be deleted, which would be kept, and how much space youβll save.
Now you can create a scheduled daily task, pointing to a specific path and removing the -WhatIf
flag:
Program/script : C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Add arguments (optional) : -NoProfile -NonInteractive -ExecutionPolicy Bypass -File C:\Scripts\Prune-Backups.ps1 -Path "C:\ProgramData\Vendor\Backups\" -Days 7 -Weeks 4 -Months 3 -Years 2
Note: No matter what, the most recent item in the folder will be kept. The default behavior of the script, if called with no parameters, is to keep only the most recent file.
deal.digital v2025 (concourse) // UNDER ACTIVE DEVELOPMENT
No rights reserved, except by respective authors of imported and referenced materials. Swim at your own risk: this software and information are provided as-is with no warranty or guarantee, express or implied.
% show system-information
Build
2025-07-29 01:58:13 UTC with Zola on GitHub Actions , hosted on GitHub Pages. View source here .
Fonts
Headings set in Instrument Serif .
Navigator
Uses Fuse.js for fuzzy search.
% tree deal.digital
deal.digital/
ββarchive/
β ββsdx1
ββblog/
β ββdesign-principles
β ββlibrechat
β ββshorelock
β ββsmart-seagate
β ββwintricks
ββtools/
β ββnetlibram
β ββprune
β ββpwgen
β ββtpmiddle
β ββwin11-hta
ββcontact
ββhome
ββlinks
ββnow
ββsample
ββtodo
ββuses
% show :3
__,,,,_
_ __..-;''`--/'/ /.',-`-.
(`/' ` | \ \ \\ / / / / .-'/`,_
/'`\ \ | \ | \| // // / -.,/_,'-,
/<7' ; \ \ | ; ||/ /| | \/ |`-/,/-.,_,/')
/ _.-, `,-\,__| _-| / \ \/|_/ | '-/.;.\'
`-` f/ ; / __/ \__ `/ |__/ |
`-' | -| =|\_ \ |-' |
__/ /_..-' ` ),' //
fL ((__.-'((___..-'' \__.'
Ο