PowerShell Disk Cleanup Script: Remove Old Temp Files

A disk-full alert at 3 AM means scrambling to identify what is eating space, manually deleting files, and hoping nothing critical was removed. Preventing that situation with a scheduled PowerShell disk cleanup script takes 30 minutes to build and runs silently every week — deleting old temp files, clearing stale logs, emptying the recycle bin, and reporting how much space was freed. This post covers each cleanup step with safety-first patterns like -WhatIf previews and age-based deletion filters.
Delete Files Older Than N Days
The foundation of any disk cleanup script is age-based file deletion. Calculate the cutoff date and compare against LastWriteTime:
function Remove-OldFiles {
param(
[string]$Path,
[int]$AgeDays = 30,
[switch]$WhatIf
)
$cutoff = (Get-Date).AddDays(-$AgeDays)
$files = Get-ChildItem -Path $Path -Recurse -File -ErrorAction SilentlyContinue |
Where-Object LastWriteTime -lt $cutoff
$totalSize = ($files | Measure-Object -Property Length -Sum).Sum
if ($WhatIf) {
Write-Host "Would delete $($files.Count) files ($([Math]::Round($totalSize / 1MB, 1)) MB) from $Path"
return 0
}
$files | Remove-Item -Force -ErrorAction SilentlyContinue
Write-Host "Deleted $($files.Count) files from $Path ($([Math]::Round($totalSize / 1MB, 1)) MB freed)"
return $totalSize
}
Clear Temp Folders
Windows Temp folders accumulate quickly. Clean the system temp folder and the current user’s temp folder, skipping files in use:
$tempPaths = @(
$env:TEMP,
$env:TMP,
"C:\Windows\Temp",
"C:\Windows\SoftwareDistribution\Download"
)
$totalFreed = 0
foreach ($path in $tempPaths) {
if (Test-Path $path) {
$freed = Remove-OldFiles -Path $path -AgeDays 7
$totalFreed += $freed
}
}
Write-Host "Total from temp folders: $([Math]::Round($totalFreed / 1MB, 1)) MB"
Empty Recycle Bin
Clear-RecycleBin is available in PowerShell 5.0 and later. Use -Force to suppress the confirmation prompt:
# Get size before clearing
$shell = New-Object -ComObject Shell.Application
$recycleBin = $shell.Namespace(0xA)
$binSize = ($recycleBin.Items() | Measure-Object -Property Size -Sum).Sum
# Clear the recycle bin for all drives
Clear-RecycleBin -Force -ErrorAction SilentlyContinue
Write-Host "Recycle bin cleared: $([Math]::Round($binSize / 1MB, 1)) MB freed"
Clear Windows Log Files
IIS logs and application log directories are common disk space culprits. Remove files older than the retention period:
$logPaths = @(
@{ Path = "C:\inetpub\logs\LogFiles"; AgeDays = 30 },
@{ Path = "C:\Logs\Application"; AgeDays = 60 },
@{ Path = "C:\Logs\Archived"; AgeDays = 90 }
)
$totalFreed = 0
foreach ($entry in $logPaths) {
if (Test-Path $entry.Path) {
$freed = Remove-OldFiles -Path $entry.Path -AgeDays $entry.AgeDays
$totalFreed += $freed
}
}
Write-Host "Total from log directories: $([Math]::Round($totalFreed / 1MB, 1)) MB"
Report Space Freed
Capture disk space before and after, and log the results with a timestamp:
function Get-DiskFreeGB {
param([string]$Drive = "C")
$disk = Get-PSDrive -Name $Drive -ErrorAction SilentlyContinue
if ($disk) { [Math]::Round($disk.Free / 1GB, 2) }
else {
(Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DeviceID='${Drive}:'").FreeSpace / 1GB
}
}
$freeBefore = Get-DiskFreeGB -Drive "C"
# ... run all cleanup operations ...
$freeAfter = Get-DiskFreeGB -Drive "C"
$gained = [Math]::Round($freeAfter - $freeBefore, 2)
$report = "Cleanup $(Get-Date): Before $freeBefore GB free → After $freeAfter GB free (gained $gained GB)"
Write-Host $report
Add-Content "C:\Logs\cleanup.log" $report
Safe Preview with -WhatIf
Before running the cleanup for the first time, preview what would be deleted without actually removing anything. The Remove-OldFiles function defined earlier accepts -WhatIf:
# Preview mode — no files are deleted
Remove-OldFiles -Path "C:\inetpub\logs\LogFiles" -AgeDays 30 -WhatIf
Remove-OldFiles -Path "C:\Windows\Temp" -AgeDays 7 -WhatIf
# When satisfied, run for real
Remove-OldFiles -Path "C:\inetpub\logs\LogFiles" -AgeDays 30
Remove-OldFiles -Path "C:\Windows\Temp" -AgeDays 7
Would delete 847 files (1243.2 MB) from C:\inetpub\logs\LogFiles
Would delete 312 files (45.8 MB) from C:\Windows\Temp
Common Errors and Fixes
-
Deleting in-use temp files throws access denied. Files locked by running processes cannot be deleted. Always use
-ErrorAction SilentlyContinuewhen deleting from temp folders to skip locked files without stopping the script. Log how many files were skipped by comparing found count to successfully deleted count. -
Recycle bin Clear-RecycleBin requires PS5+. Windows PowerShell 4 and earlier do not have
Clear-RecycleBin. On older systems, clear the recycle bin via the COM Shell object:(New-Object -ComObject Shell.Application).Namespace(0xA).Items() | ForEach-Object { Remove-Item $_.Path -Recurse -Force }.
Related Cmdlets / See Also
Wrapping Up
A disk cleanup script built with age-based file deletion, temp folder clearing, and recycle bin emptying, combined with before/after space reporting, gives you proactive disk management without manual effort. Always preview with your custom -WhatIf logic on first run, start with conservative retention periods, and schedule the script weekly with Task Scheduler.


