How to Run Disk Cleanup (cleanmgr) Silently in Batch Script
Maintaining sufficient disk space is a core responsibility for system administration. The Windows Disk Cleanup utility (cleanmgr.exe) removes temporary files, system logs, cached data, and other unnecessary files. However, by default it opens a GUI that requires manual interaction. By pre-configuring cleanup categories through the registry and using the /sagerun switch, a Batch script can trigger Disk Cleanup silently, enabling automated background maintenance.
This guide explains how to configure, execute, and schedule silent disk cleanup operations.
How Silent Disk Cleanup Works
-
Normal cleanmgr:
cleanmgr.exe- GUI opens
- User selects categories
- User clicks OK
- Cleanup runs
-
Silent cleanmgr (two-phase approach):
-
Phase 1 (one-time setup): Configure categories
- Run:
cleanmgr /sageset:100→ opens GUI for selection - OR configure via registry keys (fully automated)
- Run:
-
Phase 2 (repeated execution): Run cleanup silently
- Run:
cleanmgr /sagerun:100→ no GUI, uses saved settings
- Run:
-
The key concept is Sageset/Sagerun IDs. Each ID (a number from 1 to 65535) stores a set of cleanup categories in the registry. You configure the ID once, then run it repeatedly without any user interaction.
Many cleanup categories (Temporary Files, Internet Cache) work as a standard user. However, system-level cleanup (Windows Update files, Component Store, Memory Dumps) requires administrator privileges. For complete cleanup, always run as Administrator.
Method 1: Fully Automated Silent Cleanup (Registry-Based)
This method configures the cleanup categories directly through the registry, no manual GUI interaction required. It can be deployed to any machine without a one-time setup step.
Implementation
@echo off
setlocal
set "SageID=100"
echo ============================================================
echo Silent Disk Cleanup Utility
echo ============================================================
echo.
:: Check for admin rights
net session >nul 2>&1
if errorlevel 1 (
echo [ERROR] Administrator privileges required for system-level cleanup. >&2
echo Right-click and select "Run as administrator." >&2
endlocal
exit /b 1
)
:: Record disk space before cleanup
for /f "delims=" %%f in (
'powershell -NoProfile -Command ^
"$drive = Get-CimInstance Win32_LogicalDisk -Filter ''DeviceID=''''C:''''';" ^
"[math]::Round($drive.FreeSpace / 1GB, 2)"'
) do set "FreeBeforeGB=%%f"
echo [INFO] Free space before cleanup: %FreeBeforeGB% GB
echo.
:: =============================================
:: Configure cleanup categories via registry
:: =============================================
echo [INFO] Configuring cleanup categories...
set "RegKey=HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\VolumeCaches"
:: Define all cleanup categories to enable
:: StateFlags followed by the SageID number, value 2 = enabled
for %%c in (
"Active Setup Temp Folders"
"BranchCache"
"Delivery Optimization Files"
"Device Driver Packages"
"Downloaded Program Files"
"Internet Cache Files"
"Memory Dump Files"
"Old ChkDsk Files"
"Previous Installations"
"Recycle Bin"
"RetailDemo Offline Content"
"Service Pack Cleanup"
"Setup Log Files"
"System error memory dump files"
"System error minidump files"
"Temporary Files"
"Temporary Setup Files"
"Thumbnail Cache"
"Update Cleanup"
"Upgrade Discarded Files"
"User file versions"
"Windows Defender"
"Windows Error Reporting Archive Files"
"Windows Error Reporting Queue Files"
"Windows Error Reporting System Archive Files"
"Windows Error Reporting System Queue Files"
"Windows ESD installation files"
"Windows Upgrade Log Files"
) do (
reg add "%RegKey%\%%~c" /v StateFlags0%SageID% /t REG_DWORD /d 2 /f >nul 2>&1
)
echo [OK] Cleanup categories configured.
echo.
:: =============================================
:: Execute the silent cleanup
:: =============================================
echo [ACTION] Running Disk Cleanup (this may take several minutes^)...
echo [INFO] cleanmgr runs in the background. A progress window may briefly appear.
echo.
cleanmgr /sagerun:%SageID%
:: Wait for cleanmgr to finish (it spawns a child process)
echo [INFO] Waiting for cleanup to complete...
:WaitLoop
timeout /t 5 >nul
tasklist /fi "IMAGENAME eq cleanmgr.exe" 2>nul | findstr /i "cleanmgr" >nul
if not errorlevel 1 goto :WaitLoop
:: Also wait for DismHost if Windows Update cleanup is running
tasklist /fi "IMAGENAME eq DismHost.exe" 2>nul | findstr /i "DismHost" >nul
if not errorlevel 1 (
echo [INFO] Windows Update cleanup is running (DismHost.exe^)...
echo [INFO] This can take 10-30 minutes for large update histories.
:DismWait
timeout /t 10 >nul
tasklist /fi "IMAGENAME eq DismHost.exe" 2>nul | findstr /i "DismHost" >nul
if not errorlevel 1 goto :DismWait
)
echo.
:: =============================================
:: Measure results
:: =============================================
for /f "delims=" %%f in (
'powershell -NoProfile -Command ^
"$drive = Get-CimInstance Win32_LogicalDisk -Filter ''DeviceID=''''C:''''';" ^
"[math]::Round($drive.FreeSpace / 1GB, 2)"'
) do set "FreeAfterGB=%%f"
echo [OK] Cleanup complete.
echo Free space before: %FreeBeforeGB% GB
echo Free space after: %FreeAfterGB% GB
for /f "delims=" %%s in (
'powershell -NoProfile -Command "[math]::Round(%FreeAfterGB% - %FreeBeforeGB%, 2)"'
) do echo Space recovered: %%s GB
echo.
echo ============================================================
:: Log the operation
for /f "delims=" %%t in (
'powershell -NoProfile -Command "Get-Date -Format ''yyyy-MM-dd HH:mm:ss''"'
) do echo [%%t] CLEANUP: Before=%FreeBeforeGB%GB After=%FreeAfterGB%GB on %COMPUTERNAME% >> "%~dp0disk_cleanup.log"
endlocal
exit /b 0
Cleanup categories explained:
| Category | What It Removes | Typical Size |
|---|---|---|
| Temporary Files | User and system temp files | 100 MB – 5 GB |
| Internet Cache Files | Browser cache (IE/Edge) | 50 MB – 2 GB |
| Recycle Bin | Deleted files awaiting permanent removal | Varies widely |
| Windows Update Cleanup | Old Windows Update files | 1 – 10 GB |
| Previous Installations | Windows.old folder from upgrades | 10 – 30 GB |
| Windows ESD installation files | Downloaded upgrade files | 3 – 8 GB |
| Memory Dump Files | System crash dumps | 1 – 16 GB per dump |
| Thumbnail Cache | Explorer thumbnail database | 50 – 500 MB |
| Windows Error Reporting | Error report queues and archives | 50 MB – 1 GB |
| Delivery Optimization Files | Windows Update sharing cache | 100 MB – 5 GB |
Windows Update Cleanup and Previous Installations cleanup can take 30–60 minutes on systems with large update histories. These operations use DismHost.exe internally, which is CPU and I/O intensive. Avoid running during work hours or heavy workloads. The script monitors DismHost.exe and waits for it to finish.
Why the script waits for cleanmgr.exe and DismHost.exe:
cleanmgr /sagerun returns to the command prompt immediately while cleanup continues in the background. The script monitors the process list to detect when cleanup actually finishes, essential for accurate space-recovered measurements and for ensuring the script doesn't exit while intensive operations (like Windows Update cleanup) are still running.
Registry key format:
The registry key name follows the pattern StateFlags + four-digit zero-padded ID number:
/sagerun:100→StateFlags0100/sagerun:1→StateFlags0001/sagerun:65535→StateFlags65535
The value 2 means "enabled for this cleanup profile." Value 0 or absent means "disabled."
Method 2: Interactive Setup + Silent Execution
For environments where you want to manually choose cleanup categories once (using the GUI), then run the selected categories silently on a schedule.
Step 1: One-time configuration (interactive)
@echo off
echo [SETUP] Opening Disk Cleanup configuration...
echo [INFO] Select all categories you want included in automated cleanup.
echo [INFO] Click OK when done. This saves the configuration for future silent runs.
echo.
cleanmgr /sageset:200
echo [OK] Configuration saved as profile 200.
echo [INFO] Run silent cleanup anytime with: cleanmgr /sagerun:200
Step 2: Silent execution (repeated)
@echo off
setlocal
echo [ACTION] Running configured Disk Cleanup (profile 200^)...
cleanmgr /sagerun:200
:: Monitor completion
:WaitClean
timeout /t 5 >nul
tasklist /fi "IMAGENAME eq cleanmgr.exe" 2>nul | findstr /i "cleanmgr" >nul
if not errorlevel 1 goto :WaitClean
echo [OK] Disk Cleanup complete.
endlocal
exit /b 0
When to use Method 1 vs. Method 2:
| Scenario | Method |
|---|---|
| Deploy to many machines without manual setup | Method 1 (registry-based) |
| Administrator wants to hand-pick categories | Method 2 (GUI setup + silent run) |
| Custom categories per machine type | Method 2 (different setups on different machine roles) |
| Fully unattended automation | Method 1 |
Method 3: Additional Cleanup Beyond cleanmgr
cleanmgr doesn't cover everything. This method adds commonly needed cleanup tasks that cleanmgr doesn't handle.
@echo off
setlocal
net session >nul 2>&1
if errorlevel 1 (
echo [ERROR] Administrator privileges required. >&2
endlocal
exit /b 1
)
echo [INFO] Extended cleanup (beyond cleanmgr^)...
echo.
:: 1. Clear Windows Temp folder
echo [ACTION] Clearing Windows Temp folder...
del /q /f "%SystemRoot%\Temp\*" 2>nul
for /d %%d in ("%SystemRoot%\Temp\*") do rd /s /q "%%d" 2>nul
echo [OK] Windows Temp cleared.
:: 2. Clear user Temp folder
echo [ACTION] Clearing User Temp folder...
del /q /f "%TEMP%\*" 2>nul
for /d %%d in ("%TEMP%\*") do rd /s /q "%%d" 2>nul
echo [OK] User Temp cleared.
:: 3. Clear Windows Prefetch (improves startup after major changes)
echo [ACTION] Clearing Prefetch cache...
del /q /f "%SystemRoot%\Prefetch\*" 2>nul
echo [OK] Prefetch cleared.
:: 4. Clear font cache (fixes font display issues)
echo [ACTION] Clearing Font Cache...
net stop FontCache >nul 2>&1
del /q "%SystemRoot%\ServiceProfiles\LocalService\AppData\Local\FontCache\*" 2>nul
net start FontCache >nul 2>&1
echo [OK] Font Cache cleared.
:: 5. Flush DNS cache
ipconfig /flushdns >nul 2>&1
echo [OK] DNS cache flushed.
:: 6. Clear Windows Update download cache
echo [ACTION] Clearing Windows Update download cache...
net stop wuauserv >nul 2>&1
del /q /f "%SystemRoot%\SoftwareDistribution\Download\*" 2>nul
for /d %%d in ("%SystemRoot%\SoftwareDistribution\Download\*") do rd /s /q "%%d" 2>nul
net start wuauserv >nul 2>&1
echo [OK] Windows Update cache cleared.
echo.
echo [DONE] Extended cleanup complete.
endlocal
exit /b 0
Clearing the Prefetch cache causes a temporary slowdown in application launches as Windows rebuilds its optimization data. The Font Cache service restart may cause a brief font display glitch. These are self-healing and resolve after a few minutes. Avoid clearing these during active user sessions.
Method 4: Scheduled Maintenance Cleanup
Combine cleanmgr with extended cleanup into a single maintenance script, scheduled to run weekly during off-hours.
@echo off
setlocal
set "LogFile=%~dp0cleanup_maintenance.log"
net session >nul 2>&1
if errorlevel 1 (
echo [ERROR] Administrator privileges required. >&2
endlocal
exit /b 1
)
for /f "delims=" %%t in (
'powershell -NoProfile -Command "Get-Date -Format ''yyyy-MM-dd HH:mm:ss''"'
) do set "StartTime=%%t"
echo [%StartTime%] Maintenance cleanup started on %COMPUTERNAME% >> "%LogFile%"
:: Record space before
for /f "delims=" %%f in (
'powershell -NoProfile -Command ^
"[math]::Round((Get-CimInstance Win32_LogicalDisk -Filter ''DeviceID=''''C:''''').FreeSpace / 1GB, 2)"'
) do set "BeforeGB=%%f"
:: Phase 1: cleanmgr silent cleanup
echo [1/2] Running cleanmgr silent cleanup...
call "%~dp0silent_cleanup.bat" >nul 2>&1
:: Phase 2: Extended cleanup
echo [2/2] Running extended cleanup...
call "%~dp0extended_cleanup.bat" >nul 2>&1
:: Record space after
for /f "delims=" %%f in (
'powershell -NoProfile -Command ^
"[math]::Round((Get-CimInstance Win32_LogicalDisk -Filter ''DeviceID=''''C:''''').FreeSpace / 1GB, 2)"'
) do set "AfterGB=%%f"
for /f "delims=" %%s in (
'powershell -NoProfile -Command "[math]::Round(%AfterGB% - %BeforeGB%, 2)"'
) do set "RecoveredGB=%%s"
for /f "delims=" %%t in (
'powershell -NoProfile -Command "Get-Date -Format ''yyyy-MM-dd HH:mm:ss''"'
) do set "EndTime=%%t"
echo [%EndTime%] Complete. Before: %BeforeGB%GB After: %AfterGB%GB Recovered: %RecoveredGB%GB >> "%LogFile%"
echo [OK] Maintenance cleanup complete. Recovered %RecoveredGB% GB.
endlocal
exit /b 0
Scheduling:
:: Run weekly on Sunday at 2:00 AM
schtasks /create /tn "WeeklyDiskCleanup" /tr "\"%~dp0maintenance_cleanup.bat\"" /sc weekly /d SUN /st 02:00 /ru System /rl highest /f
Windows 10/11 includes Storage Sense, which automatically cleans temp files, Recycle Bin, and Downloads folder content. It can be configured via Settings or Group Policy. However, cleanmgr provides more granular control over specific categories and integrates better with Batch automation. For comprehensive cleanup, use both: Storage Sense for continuous background cleanup and cleanmgr scripts for periodic deep cleanup.
How to Avoid Common Errors
Wrong Way: Running /sagerun Without Prior Configuration
:: Does nothing useful - no categories have been selected for ID 99
cleanmgr /sagerun:99
If the StateFlags registry keys for the specified ID don't exist, cleanmgr /sagerun runs but cleans nothing. The command appears to succeed but removes zero files.
Correct Way: Either configure via GUI (/sageset:99) first, or set the registry keys programmatically (Method 1) before calling /sagerun.
Wrong Way: Using > to Redirect cleanmgr Output
:: cleanmgr is a GUI application - its output cannot be redirected
cleanmgr /sagerun:100 > cleanup_log.txt
:: The log file will be empty
cleanmgr.exe is a Windows GUI application that doesn't write to stdout. Redirecting its output captures nothing.
Correct Way: Measure disk space before and after (as in Method 1) to determine how much space was recovered. For process monitoring, use tasklist.
Problem: cleanmgr Returns Immediately
cleanmgr /sagerun launches the cleanup process and returns immediately, it does NOT wait for cleanup to finish. If your script measures disk space immediately after the command, it will see no change because cleanup is still running in the background.
Solution: Method 1 includes a wait loop that monitors cleanmgr.exe and DismHost.exe processes, waiting for both to exit before measuring the results.
Problem: ID Conflicts with Other Software
If another script or deployment tool uses the same sageset ID, they may overwrite each other's settings.
Solution: Use a distinctive ID number. Avoid common numbers like 1, 10, or 100 if your environment has multiple cleanup scripts. Document which IDs are in use.
Best Practices and Rules
1. Pre-Configure Categories via Registry for Fleet Deployment
Method 1's registry-based approach works on any machine without manual GUI interaction. This is the correct approach for deploying to hundreds of machines via SCCM, Group Policy, or scripts.
2. Measure Space Before and After
Silent cleanup provides no visible output. The only way to know how much space was recovered is to compare free space before and after the operation.
3. Wait for Cleanup to Actually Finish
cleanmgr /sagerun returns immediately. Monitor the cleanmgr.exe process to detect actual completion.
4. Schedule During Off-Hours
Windows Update cleanup and Previous Installations removal are CPU and I/O intensive. Schedule these for nights or weekends when user impact is minimal.
5. Use Unique Sageset IDs
Document which IDs your scripts use. Avoid conflicts with other tools that may also use cleanmgr /sageset.
6. Combine with Extended Cleanup
cleanmgr doesn't cover everything. Pair it with temp file deletion, Windows Update cache clearing, and other targeted cleanup (Method 3) for comprehensive maintenance.
Conclusion
Automating Disk Cleanup via Batch provides reliable, hands-free storage maintenance. By configuring cleanup categories through the registry and using /sagerun for silent execution, you create a deployment-ready cleanup routine that works across any number of machines without manual interaction. Combining cleanmgr with extended cleanup tasks and scheduling the combined operation weekly ensures that disk space management is proactive rather than reactive.