Shore Up
An archivist pulling the oldest dated ledgers off a shelf and dropping them into a shredder while a wall clock marks the hour, with the newest ledgers left untouched on the shelf.
Windows

Schedule and Rotate IIS Log Cleanup with a Batch File

Ketan Aagja7 min read
No ratings yet

IIS writes a fresh W3C log file on a schedule, but it never deletes the old ones. On a busy site that quietly eats the system drive until something breaks. This is the boring, reliable fix: a batch file that deletes logs older than N days, run daily by Task Scheduler.

Before you run this

What it does. The batch file uses Windows' built-in forfiles to find .log files under the IIS log directory that are older than a set number of days, and permanently deletes them. Deletion is with del — the files do not go to the Recycle Bin, and there is no undo. Once a log is gone, it is gone. Set your retention window with that in mind (compliance, security investigations, and troubleshooting often need 30–90 days).

Privileges. The batch itself needs write/delete permission on the log directory. Run the scheduled task as SYSTEM or a service account with those rights. Creating the scheduled task requires an elevated command prompt (Run as administrator). A normal user cannot register a /ru SYSTEM task.

Test first. Read the script. Before you schedule anything, run the forfiles line in a dry-run form (shown below) that only prints what it would delete, on a test copy of a log folder or a non-production server. Confirm the file list is exactly what you expect before you let it delete for real.

Assumptions. I'm writing for Windows Server 2019/2022 with IIS 10, default W3C logging, logs at C:\inetpub\logs\LogFiles (each site in a W3SVC<n> subfolder). If you moved the log location, or you run HTTPERR logs (C:\Windows\System32\LogFiles\HTTPERR) or FTP logs, adjust the path — the logic is identical. Batch/forfiles syntax has been stable across these Windows versions.

Step 1 — Confirm your log path and retention

Check where IIS is actually writing. In IIS Manager, select the server or a site → Logging → the Directory field. The default is:

C:\inetpub\logs\LogFiles

Decide your retention. I'll use 30 days as the placeholder — replace 30 throughout with your number.

Step 2 — Dry run: see what would be deleted

Open an elevated Command Prompt and run this. It lists matching files and deletes nothing:

forfiles /p "C:\inetpub\logs\LogFiles" /s /m *.log /d -30 /c "cmd /c echo @path"
  • /p — starting path
  • /s — recurse into the W3SVC* subfolders
  • /m *.log — only log files
  • /d -30 — files last modified 30 or more days ago
  • /c "cmd /c echo @path" — action: here, just echo the full path

If it prints ERROR: No files found with the specified search criteria, nothing is old enough yet — that's fine and expected on a fresh server. Review the printed list. When you're happy it's only old logs, move on.

Step 3 — Write the batch file

Save this as C:\Scripts\Clean-IISLogs.bat (create C:\Scripts if it doesn't exist). Comments explain the non-obvious lines.

@echo off
REM --- Clean-IISLogs.bat : delete IIS W3C logs older than RETENTION_DAYS ---

REM Edit these two values for your environment:
set "LOGPATH=C:\inetpub\logs\LogFiles"
set "RETENTION_DAYS=30"

REM Where to write a record of each run (folder must exist):
set "RUNLOG=C:\Scripts\iis-log-cleanup.log"

echo ================================================= >> "%RUNLOG%"
echo Run started: %DATE% %TIME% >> "%RUNLOG%"

REM Delete matching files; append each deleted path to the run log.
forfiles /p "%LOGPATH%" /s /m *.log /d -%RETENTION_DAYS% /c "cmd /c del @path && echo Deleted @path" >> "%RUNLOG%" 2>&1

echo Run finished: %DATE% %TIME% >> "%RUNLOG%"
echo. >> "%RUNLOG%"

Notes:

  • forfiles sets a non-zero exit code when it finds no matching files. That is normal, not a failure — Task Scheduler will show 0x1 on quiet days. Don't treat that as an error.
  • The del @path runs once per matched file. The && echo only logs paths that actually deleted.
  • Keep RUNLOG outside LOGPATH so the cleanup can't ever match and delete its own record.

Test the batch on a copy first. Point LOGPATH at a throwaway folder full of old dummy .log files (set their dates back, or just accept that new files won't match) and run it once by double-clicking or from the elevated prompt. Confirm iis-log-cleanup.log records what you expect. Only then point it at the real path.

Step 4 — Schedule it with Task Scheduler

Register a daily task from an elevated prompt. This runs the batch at 02:00 as SYSTEM:

schtasks /create ^
  /tn "IIS Log Cleanup" ^
  /tr "C:\Scripts\Clean-IISLogs.bat" ^
  /sc daily ^
  /st 02:00 ^
  /ru "SYSTEM" ^
  /rl HIGHEST
  • /tn — task name
  • /tr — the program/batch to run
  • /sc daily /st 02:00 — daily at 2 AM (pick a quiet hour)
  • /ru "SYSTEM" — run as the local SYSTEM account (has rights to the default log path)
  • /rl HIGHEST — run with highest privileges

The ^ characters are line continuations for cmd — you can also write it as one long line. If you prefer a dedicated service account instead of SYSTEM, use /ru DOMAIN\svc-account /rp and supply its password; that account must have delete rights on the log directory.

For the full set of schtasks and forfiles switches, see the Windows Commands reference on Microsoft Learn (schtasks and forfiles pages) rather than guessing any option I haven't shown here.

Step 5 — Verify

Run the task on demand and check the outcome:

REM Fire the task now instead of waiting for 02:00
schtasks /run /tn "IIS Log Cleanup"

REM Confirm it exists and check its last result
schtasks /query /tn "IIS Log Cleanup" /v /fo LIST

In the /query output, look at Last Run Time and Last Result. 0 means success; 1 typically means forfiles matched nothing that run — acceptable. Then open C:\Scripts\iis-log-cleanup.log and confirm the timestamps and any Deleted ... lines match what you expect.

You can also confirm from the GUI: Task SchedulerTask Scheduler LibraryIIS Log CleanupHistory tab shows each run and its result.

To sanity-check retention, list the oldest surviving file:

forfiles /p "C:\inetpub\logs\LogFiles" /s /m *.log /d -30 /c "cmd /c echo @path @fdate"

After a successful run, this should print nothing (or only files that aged past the window since the last run).

Undo and rollback

  • Remove the schedule (the batch will simply stop running; nothing else changes):
schtasks /delete /tn "IIS Log Cleanup" /f
  • Change retention — edit RETENTION_DAYS in the batch. Increasing it keeps more logs going forward; it cannot bring back logs already deleted.
  • Deleted logs are not recoverable from this process. If you need them back, restore from your file-system backup or VSS snapshot of the log volume. If a legal/security hold requires longer retention, raise RETENTION_DAYS (or ship logs off-box before cleanup) before this task ever runs.

That's the whole job: forfiles does the rotation, Task Scheduler does the timing, and the run log gives you a paper trail. It's the standard approach, and it stays out of your way once it's set.

Written by
Ketan Aagja

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.