If your like me you have a lot of backups, downloads, and/or copies files in various folders and cleaning it up and can be time consuming. To help with that I put together this small powershell script/function that will help clean it up (or at least handle the removing of items based on being way to old!)
To use the script, copy/paste it into your favorite editor, save it as “Remove-AgedFiles.ps1” to an easy to remember location (Desktop, your scripts folder, etc) and you are ready to go.
Usage would look like this:
[PS] .\Remove-ItemsItems.ps1 -Path e:\Downloads -NumberOfDaysOld 10
Note: script support the -WhatIf and -Debug standard parameters so that you can run it without actually changing anything on the system so you can run it like this to see what files will be deleted without actually having them removed from you system (great for validating what is going to be done as a sanity check)
[PS] .\Remove-ItemsItems.ps1 -Path e:\Downloads -NumberOfDaysOld 10 -WhatIf -Debug
And without further adieu here is the actual script
[CmdletBinding(SupportsShouldProcess)] param ( [Parameter(Mandatory)] [IO.DirectoryInfo] $Path, [int] $NumberOfDaysOld = 30, [Switch] $IgnoreEmptFolders, [DateTime] $now = [DateTime]::MinValue, [String] $LogFile = "$((Get-Location).Drive.Name)\AgedFiles-$($env:computername)-$((Get-Date).ToString("yyyyMMdd")).log" ) function Write-Log { param([string]$message) $msg = (((Get-Date).ToString()) + " - " + $Message) Write-Host $msg Add-Content $LogFile -value $msg } if (Test-Path $LogFile) { Write-Host "Removing previous log file" -ForegroundColor Yellow Remove-Item $LogFile } # Do we have a valid dates? If note lets get the current date if ($now -eq [DateTime]::MinValue) { $now = (Get-Date) } $retentionPeriod = [TimeSpan]::FromDays($NumberOfDaysOld) Write-Log "Starting process of removing aged files" # Lets find all of the files that haven't been "changed" in the last X days Write-Log "Retrieving list of files older than '$($retentionPeriod.Days)' days to remove" $oldFiles = Get-ChildItem $Path.FullName -Recurse -File -ErrorAction SilentlyContinue | Where-Object { $_.LastWriteTime -lt $now.Subtract($retentionPeriod) } # Lets get a lost of all of the folders we need to process and then filter them down to only the empty ones that can be removed if (-Not ($IgnoreEmptFolders.IsPresent)) { Write-Log "Retrieving list of folders to remove" $folders = Get-ChildItem $Path.FullName -Recurse -Directory -ErrorAction SilentlyContinue $emptyFolders = $folders ` | Where-Object { (Get-ChildItem $_.FullName -file -Recurse -ErrorAction SilentlyContinue | Where-Object { $_.LastWriteTime -gt $now.Subtract($retentionPeriod) }) -eq $null } ` | Sort-Object -Property @{ Expression={ $_.FullName.Split([IO.Path]::DirectorySeparatorChar).Count }; Descending=$true } } # Lets delete all of the old files Write-Log "Removing Files older than '$($retentionPeriod.Days)' days" Write-Debug "Files to remove: `n`t$(($oldFiles | Select -ExpandProperty FullName) -join "`r`n`t")" if ($PSCmdlet.ShouldProcess($Path.FullName, "Remove files older than '$($retentionPeriod.Days)' days")) { $oldFiles | Remove-Item -Force -Verbose | Out-File $LogFile -Append } else { $oldFiles | Out-File $LogFile -Append } if (-Not ($IgnoreEmptFolders.IsPresent)) { # Lets delete all of the empty folders Write-Log "Cleaning up empty folders" Write-Debug "Folders to remove: `n`t$(($oldFiles | Select -ExpandProperty FullName) -join "`r`n`t")" if ($PSCmdlet.ShouldProcess($Path.FullName, "Remove empty folders")) { $emptyFolders | Remove-Item -Force -Recurse -Verbose | Out-File $LogFile -Append } else { $emptyFolder | Out-File $LogFile -Append } } Write-Log "Completed process of removing aged files"