A few years ago I think I posted some PowerShell clean up tools. These were functions designed to help clear out old files, especially for folders like TEMP. Recently I decided to upgrade them to at least PowerShell 3.0 to take advantage of v3 cmdlets and features. I use these periodically to clean out my temp folders. I should probably set them up as a scheduled job to run monthly, but I haven't gotten around to that yet. In the mean time, let me show you what I have.
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
First, I have a function to delete files from a directory that were last modified after a given date.
#requires -version 3.0 Function Remove-File { <# .SYNOPSIS Delete files based on file age. .DESCRIPTION This function will go start at a specified path and delete files and folders that are older than a specified date and time. The comparison is made to the file's last modified time. The last access time doesn't always accurately reflect when a file was last used. Typically you will use this function to clean out temp folders. .PARAMETER Path The folder path to search. The default is the temp folder. .PARAMETER Cutoff The date time threshold .PARAMETER Recurse Recursively search from the starting path. .PARAMETER Hidden Include hidden and system files files. .EXAMPLE PS C:\> Remove-File -recurse -cutoff (Get-CimInstance -ClassName Win32_OperatingSystem).LastBootUpTime -whatif Remove all files in the temp folder that are older than the computer's startup time. .EXAMPLE PS C:\> "C:\work","$env:temp","$env:windir\temp" | Remove-File -cutoff (Get-Date).AddDays(-30) -recurse -hidden This command will search the 3 specified paths for all files that haven't been modified in 30 days and delete them. .NOTES NAME : Remove-File VERSION : 3.0 LAST UPDATED: 11/11/2013 AUTHOR : Jeffery Hicks .LINK https://jdhitsolutions.com/blog/2013/11/powershell-clean-up-tools .LINK Get-ChildItem Remove-Item .INPUTS String .OUTPUTS None #> [cmdletbinding(SupportsShouldProcess)] Param( [Parameter(Position=0)] [ValidateScript({Test-Path $_})] [string]$Path=$env:temp, [Parameter(Position=1,Mandatory, HelpMessage= "Enter a cutoff date. All files after this date will be removed.")] [ValidateScript({$_ -lt (Get-Date)})] [datetime]$Cutoff, [Switch]$Recurse, [Switch]$Hidden ) Write-Host "Removing files in $path older than $cutoff" -foregroundcolor CYAN #create a hashtable of parameters to splat to Get-ChildItem $paramHash=@{ Path= $Path ErrorAction= "Stop" File= $True } #add optional parameters if ($Recurse) { $paramHash.Add("Recurse",$True) } if ($Hidden) { $paramHash.Add("Force",$True) } Try { $files = Get-ChildItem @paramhash | where {$_.lastwritetime -lt $cutoff} } Catch { Write-Warning "Failed to enumerate files in $path" Write-Warning $_.Exception.Message #Bail out Return } if ($files) { #only remove files if anything was found $files| Remove-Item -Force $stats= $files | Measure-Object -Sum length $msg="Attempted to delete {0} files for a total of {1} MB ({2} bytes)" -f $stats.count,($stats.sum/1MB -as [int]),$stats.sum Write-Host $msg -foregroundcolor CYAN } #if $files else { Write-Host "No files found to remove" -ForegroundColor Yellow } } #close function
The function supports -WhatIf so that if I run it, Remove-Item will only show me what it would delete. I use a hashtable to build a set of parameters to splat to Get-ChildItem. I love this technique for building dynamic commands. I use this command on my temp folders to delete files older than the last time the computer booted. My assumption is that anything in TEMP older than the last boot time is fair game for deletion.
If you look at this function, you'll notice that it only affects files. It leaves folder alone. I suppose I could modify it to remove old folders as well, but there's a chance the folder might have a newer file somewhere in the hierarchy that shouldn't be deleted so I decided to simply focus on old files. To clean up folders, I use this:
#requires -version 3.0 #remove directories that have no files. <# **************************************************************** * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED * * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK. IF * * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, * * DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING. * **************************************************************** #> Function Remove-EmptyFolder { [cmdletbinding(SupportsShouldProcess)] Param( [Parameter(Position=0,Mandatory,HelpMessage="Enter a root directory path")] [ValidateScript({Test-Path $_})] [string]$Path=$env:temp ) Write-Host "Removing empty folders in $Path" -ForegroundColor Cyan #get top level folders $Folders = Get-ChildItem -Path $path -Directory -Force #test each folder for any files foreach ($folder in $folders) { If (-NOT ($folder | dir -file -Recurse)) { Write-Host "Removing $($folder.FullName)" -ForegroundColor Red $folder | Remove-Item -Force -Recurse } } #end foreach } #end Remove-EmptyFolder
This command looks for empty folders, or more precisely folders with no files. The function gets all of the top-level folders in the specified path and then searches each folder recursively for any files. If no files are found, the folder is removed.
The two tools are great on their own. To put them to use, I created a small script.
#requires -version 3.0 <# CleanTemp.ps1 **************************************************************** * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED * * THOROUGHLY IN A LAB SETTING. USE AT YOUR OWN RISK. * * **************************************************************** #> #dot source functions . C:\scripts\Remove-EmptyFolder.ps1 . C:\scripts\Remove-File3.ps1 #get last boot up time. #Get-CIMInstance will return LastBootUpTime as a datetime object. No converting required. $bootTime = (Get-CimInstance -ClassName Win32_OperatingSystem).LastBootUpTime #delete files in temp folders older than the last bootup time Remove-File $env:temp $boottime -recurse -hidden Remove-File D:\Temp $boottime -recurse -hidden Write-Host "Removing empty folders" -ForegroundColor Cyan Remove-EmptyFolder $env:temp Remove-EmptyFolder D:\temp
I think of the script as a "canned" PowerShell session. Instead of my typing the commands to clean up a few folders, I simply run the script. I inserted some Write-Host commands so I could know what the script was doing. I clean out all the old files first and then make a second pass to delete any empty folders. I trust it goes without saying that if you want to use these, you have to test in a non-production environment.
Enjoy.
2 thoughts on “PowerShell Clean Up Tools”
Comments are closed.