— Kiaasa Dhanori Pune

A simple Windows batch script to remove empty directories walks a folder tree from the bottom up and deletes any folder that contains no files or subfolders. The key trick is to recurse into subfolders first, then attempt to delete the parent — because a folder only becomes empty after its empty children are gone. Below is a corrected, production-ready script, a PowerShell alternative, and the pitfalls that quietly break the naive versions you find online.
The problem: nested empty folders
Empty directories pile up after archive extractions, failed installs, log rotation, data-retention purges, and source-control checkouts. They clutter file listings, confuse backup jobs, and can trip up scripts that iterate folders. The native RD (remove directory) command refuses to delete a folder that still has contents, so you cannot just point it at the top of the tree and expect it to clean everything.
The challenge is nesting. Consider A\B\C where every level is otherwise empty. If you try to delete A first, it fails because it still contains B. You must delete C, then B, then A — deepest first. That bottom-up order is exactly what a recursive batch script gives you.
The solution: a recursive batch script to remove empty directories
This is the cleaned-up, working version. The original snippet circulating online is correct in spirit but is usually pasted with broken HTML entities ( , >) that must be stripped before it will run. Save the following as cleanempty.bat:
@echo off
setlocal ENABLEEXTENSIONS
rem Usage: cleanempty.bat "C:\path\to\start"
if "%~1"=="" (
echo Usage: %~nx0 "folder"
goto :EOF
)
call :rmEmptyDirs "%~1"
goto :EOF
:rmEmptyDirs
rem Recurse into every subfolder FIRST (bottom-up)
for /d %%A in ("%~1\*") do (
call :rmEmptyDirs "%%~fA"
)
rem Then try to remove THIS folder; RD only succeeds if it is empty
rd "%~f1" >nul 2>&1
goto :EOF
Run it from a command prompt by passing the folder you want to clean as a quoted argument:
- Open Command Prompt (
cmd.exe). - Change to where you saved the script, e.g.
cd C:\scripts. - Run it against your target, e.g.
cleanempty.bat "D:\Archive".
Note that the script will also delete the top folder itself if it ends up empty. If you want to keep the root and only clean its contents, see the variant further down.
How the script works, line by line
Each piece matters, and removing any one of them changes the behavior in subtle ways.
| Line | What it does |
@echo off | Stops every command from being printed, keeping output clean. |
setlocal ENABLEEXTENSIONS | Turns on command extensions so for /d and call :label behave correctly. Localizes any variables to this script. |
for /d %%A in ("%~1\*") | The /d flag iterates directories only, not files. %~1 is the first argument with surrounding quotes stripped. |
call :rmEmptyDirs "%%~fA" | The recursive call. %%~fA expands to the full absolute path of the subfolder, which avoids path-resolution bugs. |
rd "%~f1" >nul 2>&1 | Attempts to remove the current folder. RD fails harmlessly on non-empty folders; >nul 2>&1 hides both normal output and the error message. |
The magic is the order of operations: the for loop fully processes (and empties) every child before the rd on the parent ever runs. That is what makes a single pass clean an arbitrarily deep tree.
Why "%%~fA" and not just "%%A"
Inside a for /d loop, %%A can be a relative name depending on how the loop was entered. The ~f modifier forces a fully qualified path, so the recursive call always receives an unambiguous absolute location. This prevents the classic bug where deep recursion silently operates on the wrong working directory.
Variant: keep the top folder, clean only inside it
For data-retention jobs you often want to wipe empty subfolders but preserve the root (so scheduled tasks pointing at it never break). Split the logic so the entry point recurses into children but never deletes the root:
@echo off
setlocal ENABLEEXTENSIONS
if "%~1"=="" goto :EOF
rem Clean children only; never remove the root itself
for /d %%A in ("%~1\*") do call :rmEmptyDirs "%%~fA"
goto :EOF
:rmEmptyDirs
for /d %%A in ("%~1\*") do call :rmEmptyDirs "%%~fA"
rd "%~f1" >nul 2>&1
goto :EOF
The modern alternative: PowerShell
Batch scripting is fully supported on Windows 11 and Windows Server, but for new automation PowerShell is the recommended, more readable tool. It is built into every supported Windows version and handles long paths, spaces, and Unicode names far more gracefully than cmd.exe.
This one-liner removes empty directories recursively, deepest-first. The Sort-Object by descending path length guarantees children are processed before parents:
$root = "D:\Archive"
Get-ChildItem -Path $root -Directory -Recurse |
Sort-Object { $_.FullName.Length } -Descending |
Where-Object { (Get-ChildItem $_.FullName -Force | Measure-Object).Count -eq 0 } |
Remove-Item -Force
A few important details:
-Forceon the innerGet-ChildItemensures hidden and system files (likedesktop.iniorThumbs.db) are counted, so a folder that only contains hidden junk is correctly seen as non-empty.- Descending length sort is a reliable, simple way to enforce bottom-up deletion without writing explicit recursion.
- Add
-WhatIftoRemove-Itemto preview deletions before committing — essential for a first run.
Common pitfalls
These are the mistakes that turn a "working" script into a data-loss incident or a silent no-op.
- Broken copy-paste characters. Snippets from web pages often contain
(non-breaking spaces) or smart quotes instead of plain spaces and ASCII". These produce cryptic syntax errors. Retype suspicious whitespace and quotes. - Hidden files make folders look empty. Plain
RDtreats a folder with only hidden files as not empty and refuses to delete it — which is actually the safe default. Do not addRD /Sto force it unless you truly want to delete hidden contents too. - Using
RD /Sby accident.RD /S "folder"deletes the folder and everything inside it, empty or not. That is the opposite of this task. The script above deliberately uses bareRD. - Spaces in paths. Always quote arguments (
"%~1","%%~fA"). An unquoted path with spaces will be split into multiple arguments and silently target the wrong folder. - Missing
ENABLEEXTENSIONS. On locked-down machines where extensions are disabled by policy,for /dandcall :labelfail. Enabling them explicitly at the top makes the script portable. - Running with the wrong permissions. Folders owned by other users or protected by ACLs will not delete; the errors are hidden by
2>&1. Remove the redirection temporarily if folders survive unexpectedly, so you can read the real error.
Verification: confirm it actually worked
Never trust a cleanup script blindly. Verify before and after:
- Count empty folders first. In PowerShell, run a read-only count of empties so you have a baseline:
Get-ChildItem "D:\Archive" -Directory -Recurse | Where-Object { (Get-ChildItem $_.FullName -Force | Measure-Object).Count -eq 0 } | Measure-Object - Dry-run. Use the PowerShell version with
-WhatIf, or temporarily replacerdin the batch script withecho rdto print what would be deleted. - Run the real cleanup.
- Re-count. Run the count from step 1 again — it should report
Count : 0(or only the folders you intentionally kept). - Spot-check the tree. Run
dir "D:\Archive" /s /a:dto list remaining directories and confirm only meaningful ones survive.
For scheduled, unattended use, log results by appending output to a file: cleanempty.bat "D:\Archive" >> C:\logs\cleanup.log 2>&1, then review the log periodically.
Key Takeaways
- Always delete empty folders bottom-up — recurse into children first, then attempt to remove the parent.
- Use bare
RD(notRD /S); it deletes a folder only when truly empty, which is the safe behavior you want. - Quote every path and use
%%~fAfor fully qualified paths to survive spaces and deep nesting. - Watch for hidden files — add
-Forcein PowerShell so hidden junk does not make a folder falsely appear empty. - For new automation, prefer the PowerShell approach with
-WhatIffor a safe, readable, previewable cleanup.
Frequently Asked Questions
How do I delete empty folders without deleting files?
Use the recursive batch script or PowerShell command above, both of which rely on the plain RD / Remove-Item behavior that refuses to delete any folder still containing files. Avoid RD /S, which would delete files too.
Why does my script leave some empty folders behind?
The usual cause is hidden or system files (like Thumbs.db or desktop.ini) inside them — the folder is not actually empty. Either delete those files first, or count contents with -Force in PowerShell to detect them. ACL/permission errors hidden by output redirection are the second most common cause.
Can I remove empty directories in PowerShell instead of batch?
Yes, and it is the modern recommendation. Pipe Get-ChildItem -Directory -Recurse through a descending path-length sort, filter for zero contents, and pipe to Remove-Item. Add -WhatIf first to preview exactly which folders will be removed.
Will the batch script delete the top folder I point it at?
The first version will, if that folder ends up empty. Use the "keep the top folder" variant shown above, which recurses into the root's children but never runs RD on the root itself.
If this helped, subscribe on YouTube @explorenystream for more practical Windows and sysadmin tips.