Problem overview
Excessive temporary files, leftover system updates, and cluttered Downloads folders can rapidly consume drive capacity, compromise performance, and frustrate end-users. Manual removal of these files is time-consuming and prone to error, making automated cleanup essential for maintaining a healthy Windows environment.
<#
This resource is provided as a convenience for Level users. We cannot
guarantee it will work in all environments. Please test before deploying
to your production environment. We welcome contributions to our community
library
Level Library
https://level.io/library/script-windows-disk-cleanup
#>
# Create log file to track deleted files
$logFile = "C:\cleanup_log_$(Get-Date -Format 'yyyy-MM-dd_HH-mm').txt"
"Cleanup Started at $(Get-Date)" | Out-File $logFile
# Initialize total space saved
$totalSpaceSaved = 0
function Write-LogAndConsole {
param($message)
$message | Out-File $logFile -Append
Write-Host $message
}
# List of temporary folders to clean
$tempPaths = @(
"$env:TEMP",
"$env:SystemRoot\Temp",
"$env:SystemRoot\Prefetch",
"$env:SystemRoot\SoftwareDistribution\Download"
)
# Clean each temp location
foreach ($path in $tempPaths) {
Write-LogAndConsole "`nCleaning $path..."
Get-ChildItem -Path $path -Recurse -Force -ErrorAction SilentlyContinue |
Where-Object {
$_.LastAccessTime -lt (Get-Date).AddHours(-1) -and
!$_.PSIsContainer
} |
ForEach-Object {
try {
$size = $_.Length / 1MB
$fileName = $_.Name
Remove-Item -Path $_.FullName -Force -ErrorAction SilentlyContinue
$totalSpaceSaved += $size
Write-LogAndConsole "Cleaned temp file: $fileName - Freed $([math]::Round($size, 2)) MB"
}
catch {
Write-LogAndConsole "Error cleaning $fileName"
}
}
}
# Clean Downloads folders for all users
Write-LogAndConsole "`nCleaning Downloads folders..."
$userProfiles = Get-ChildItem "C:\Users" -Directory | Where-Object { $_.Name -notin @("Public", "Default", "Default User") }
foreach ($profile in $userProfiles) {
$downloadPath = Join-Path $profile.FullName "Downloads"
if (Test-Path $downloadPath) {
Write-LogAndConsole "`nCleaning Downloads folder for $($profile.Name)..."
Get-ChildItem -Path $downloadPath -Recurse -File -ErrorAction SilentlyContinue |
Where-Object { $_.LastAccessTime -lt (Get-Date).AddDays(-30) } |
ForEach-Object {
try {
$size = $_.Length / 1MB
$fileName = $_.Name
Remove-Item -Path $_.FullName -Force -ErrorAction SilentlyContinue
$totalSpaceSaved += $size
Write-LogAndConsole "Cleaned old download: $fileName - Freed $([math]::Round($size, 2)) MB"
}
catch {
Write-LogAndConsole "Error cleaning $fileName"
}
}
}
}
# Convert MB to GB for final summary
$totalGBSaved = $totalSpaceSaved / 1024
Write-LogAndConsole "`nCleanup completed at $(Get-Date)"
Write-LogAndConsole "Total space saved: $([math]::Round($totalGBSaved, 2)) GB"
Write-LogAndConsole "Log file saved to: $logFile" This script scans common Windows temp directories, Windows Update download folders, and each user’s Downloads folder for old or unnecessary items. It removes files that surpass a specified age threshold and then logs every cleaned file along with the total space reclaimed, ensuring full transparency. You can configure a script-based monitor in Level to trigger this cleanup whenever disk space is running low, or you can schedule it as part of a Level automation to keep systems tidy on a regular basis.
Use cases
- Rapidly reclaim disk space on clients with minimal free space
- Run preventative maintenance for MSP clients at scale
- Clean up Windows endpoints affected by large software updates
- Integrate on-demand execution with Level to address disk issues in real time
Recommendations
- Test the script in a non-production environment first
- Update folder paths if your organization stores data in custom locations
- Consider a script-based monitor in Level to automatically run the script when disk space is below a threshold
- Build a Level automation with a scheduled trigger for routine cleanups
- Review the generated log file to confirm successful deletion