
Automate Temp and Log Cleanup with a Batch File
Before you run this
This guide builds a Windows batch file that deletes old log files from a folder you name and temporary files from a temp folder, based on how many days ago each file was last modified. Its purpose is to reclaim disk space on a schedule without you having to remember to do it.
A few things you need to know before you touch it:
delandforfilesdo not use the Recycle Bin. Command-line deletions are permanent. There is no "restore from Recycle Bin" afterward. Treat every deletion this script makes as gone for good.- Privileges depend on where you point it. Cleaning your own user's
%TEMP%needs no elevation. Cleaning a shared log directory,C:\Windows\Temp, or another user's files needs an elevated (Administrator) command prompt, and when you schedule it you will typically run it asSYSTEMor an admin account. - Test first, and I mean it. The script ships with
DRYRUN=1, which only logs what it would delete and deletes nothing. Read the script, run it in dry-run mode, and inspect the run log before you ever setDRYRUN=0. Do this on a test VM or a throwaway copy of a folder first, not on a production server. - Point it at a folder you actually own the contents of. Never aim this at
C:\, a whole profile, or a program's data directory. It selects by file mask and age, but a wrong path plus a broad mask is exactly how people delete things they needed.
I'm assuming Windows 10/11 or Windows Server 2016+, the built-in cmd.exe and forfiles.exe (present on all of these), and Task Scheduler for automation.
What the script does, in plain terms
forfiles walks a folder, filters by file mask and last-modified age, and runs a command for each match. That's the whole engine here. The /D -30 argument selects files whose last modified date is 30 or more days in the past — note it's modified date, not created date.
The script
Save this as cleanup.bat. Every value you need to change is in the configuration block at the top, marked with obvious placeholders.
@echo off
setlocal enableextensions
REM ===== Configuration - edit these =====
REM 1 = only log what WOULD be deleted (safe). 0 = actually delete.
set "DRYRUN=1"
REM Files last modified this many or more days ago are targeted.
set "MAXAGE=30"
REM Folder to clean of old log files. Replace with your real path.
set "LOGDIR=C:\path\to\logs"
REM Which files count as logs.
set "LOGMASK=*.log"
REM Temp folder to clean. %TEMP% is the temp of the account that RUNS this.
set "TEMPDIR=%TEMP%"
REM This script's own run log - so you can see what happened.
set "RUNLOG=C:\path\to\cleanup-run.log"
REM ======================================
echo ==== Cleanup %DATE% %TIME% (DRYRUN=%DRYRUN%, MAXAGE=%MAXAGE%) ==== >> "%RUNLOG%"
REM --- Old log files ---
if exist "%LOGDIR%" (
if "%DRYRUN%"=="1" (
REM /S recurses subfolders; /D -%MAXAGE% picks files older than the threshold
forfiles /P "%LOGDIR%" /S /M %LOGMASK% /D -%MAXAGE% /C "cmd /c echo WOULD DELETE @path" >> "%RUNLOG%" 2>&1
) else (
forfiles /P "%LOGDIR%" /S /M %LOGMASK% /D -%MAXAGE% /C "cmd /c del /q @path && echo DELETED @path" >> "%RUNLOG%" 2>&1
)
) else (
echo SKIP: log folder not found: %LOGDIR% >> "%RUNLOG%"
)
REM --- Temp files ---
if exist "%TEMPDIR%" (
if "%DRYRUN%"=="1" (
forfiles /P "%TEMPDIR%" /S /M *.* /D -%MAXAGE% /C "cmd /c if @isdir==FALSE echo WOULD DELETE @path" >> "%RUNLOG%" 2>&1
) else (
forfiles /P "%TEMPDIR%" /S /M *.* /D -%MAXAGE% /C "cmd /c if @isdir==FALSE del /q @path && echo DELETED @path" >> "%RUNLOG%" 2>&1
)
) else (
echo SKIP: temp folder not found: %TEMPDIR% >> "%RUNLOG%"
)
echo ==== Done %DATE% %TIME% ==== >> "%RUNLOG%"
endlocal
A few notes on the non-obvious parts:
@isdir==FALSE— when I clean temp with a*.*mask,forfilesalso matches subfolders. Theif @isdir==FALSEtest makes suredelonly ever runs on files, never on directories.delcan't delete a folder anyway, but this keeps the log clean and the intent clear.- Empty subfolders are left behind. This script deletes files, not directories. That's deliberate — removing folders is riskier and rarely worth it. If you truly need to prune empty temp subfolders, do that as a separate, carefully reviewed step; I'm not folding it in here.
- Locked files are skipped. If a file is in use,
delreports it can't delete it and moves on. That message lands in your run log, which is fine and expected. - "ERROR: No files found…" — if nothing matches the age filter,
forfilesprints this to stderr. It's harmless;2>&1just routes it into your run log so you can see it.
Run it in dry-run mode first
Open a command prompt (elevated only if your target folders need it), then:
C:\path\to\cleanup.bat
Nothing is deleted while DRYRUN=1. Open the run log and read every WOULD DELETE line:
notepad C:\path\to\cleanup-run.log
Confirm the paths are all files you genuinely want gone. If anything on that list surprises you, fix your LOGDIR, LOGMASK, or MAXAGE and run the dry run again. Only when the list is clean do you change set "DRYRUN=1" to set "DRYRUN=0" and run it for real.
Schedule it with Task Scheduler
The mainstream way to automate this is Task Scheduler. You can build the task in the GUI (taskschd.msc), or create it from an elevated prompt with schtasks:
schtasks /Create /TN "Temp and Log Cleanup" /TR "C:\path\to\cleanup.bat" /SC DAILY /ST 02:00 /RU SYSTEM /RL HIGHEST
/RU SYSTEMruns the task as the local system account (no password needed) with the rights to clean shared folders. If you'd rather run as a specific admin, use/RU DOMAIN\userand you'll be prompted for a password.- Watch the
%TEMP%caveat:%TEMP%resolves to the running account's temp folder. UnderSYSTEMthat's not your interactive user's temp. If you want to clean a specific temp location regardless of account, setTEMPDIRto an explicit path instead of%TEMP%. /RL HIGHESTruns elevated. Confirm the exactschtasksoptions against Microsoft Learn'sschtasksreference before relying on the command in production.
Verify it worked
After a real run, check three things.
Read the run log for DELETED lines and any errors:
notepad C:\path\to\cleanup-run.log
Confirm no old files remain past the threshold. This lists any log files still older than MAXAGE — you want it to print nothing but the "No files found" message:
forfiles /P "C:\path\to\logs" /S /M *.log /D -30 /C "cmd /c echo STILL OLD: @path @fdate"
Check that the scheduled task exists and see its last result:
schtasks /Query /TN "Temp and Log Cleanup" /V /FO LIST
Undo and rollback
The file deletions themselves cannot be undone — that's the nature of del. Your only real safeguards are the ones baked in above: the dry-run pass and the run log. If you need to recover something a real run removed, you're into file-recovery tooling or your backups, so make sure old logs you might still want are backed up before you switch off dry-run.
Removing the automation is reversible. Delete the scheduled task with:
schtasks /Delete /TN "Temp and Log Cleanup" /F
That stops future runs and leaves the batch file and its run log in place for review.
Runs enterprise networks and security for a living, and writes Shore Up to turn two decades of hands-on Linux, Windows and mail-server work into guides you can actually use.
More about the author →Was this article helpful?
Tap a star — no sign-in needed.
Be the first to rate this article.
