How to Remove Empty Directories with PowerShell, or Robocopy

Removing empty directories in Windows 10 is really simple with a small PowerShell script or RoboCopy cmd. There is really no need to install any program to clean up the empty directories on your computer or server.

With the use of PowerShell or RoboCopy, both included in Windows 10, we can delete all empty folders and subfolders. It’s always a good idea to list the empty directories first, so I added the option in both scripts.

Below an example for both scripts. I have also tested the PowerShell and RoboCopy script against a directory with 11.000 empty subdirectories to see which option is the fastest.

Remove Empty Directories with PowerShell

Below you will find the script to remove empty directories with PowerShell. If you want to test the script first, which I really recommend doing, then you can set the variable $whatif to $true.

Windows makes a hidden file, Thumbs.db, in folders with images in it. These folders appear to be empty, even with show hidden files in Explorer, you don’t see the Thumbs.db. So to remove those empty folders as well you can set removeHiddenFiles to $true.

The script will then ignore the hidden files and remove the folder including the hidden files with it.

# Set to true to test the script
$whatIf = $true

# Remove hidden files, like thumbs.db
$removeHiddenFiles = $false

# Get hidden files or not. Depending on removeHiddenFiles setting
$getHiddelFiles = !$removeHiddenFiles

# Remove empty directories locally
Function Delete-EmptyFolder($path)
{
    # Go through each subfolder, 
    Foreach ($subFolder in Get-ChildItem -Force -Literal $path -Directory) 
    {
        # Call the function recursively
        Delete-EmptyFolder -path $subFolder.FullName
    }

    # Get all child items
    $subItems = Get-ChildItem -Force:$getHiddelFiles -LiteralPath $path

    # If there are no items, then we can delete the folder
    # Exluce folder: If (($subItems -eq $null) -and (-Not($path.contains("DfsrPrivate")))) 
    If ($subItems -eq $null) 
    {
        Write-Host "Removing empty folder '${path}'"
        Remove-Item -Force -Recurse:$removeHiddenFiles -LiteralPath $Path -WhatIf:$whatIf
    }
}

# Run the script
Delete-EmptyFolder -path "C:\enter\your\path\here"

In the script, we first set the WhatIf mode. This way we can test the script without actually removing any folders.

Next, we have the function Delete-EmptyFolder. The function will go through each subfolder of the given path and calls the function recursively to process the subfolders as well.

If there aren’t any subfolders, then it will request all child items in the current folder. If there aren’t any child items, then the script will remove the empty directories.

How fast is PowerShell with removing empty directories?

removing empty directories

I tested both scripts against a directory with 11.000 empty subdirectories, going 3 levels deep. PowerShell needed 12 secs to remove all empty directories. That is when you disable the Write-Host output on line 27. With the output, it took 24 secs in total.

Running the script

The easiest way to run this script is to open the Windows PowerShell ISE. This way you can easily change the path and WhatIf variable. Windows PowerShell ISE is also a standard program of Windows 10 which you will find in your Start Menu.

removing empty directories in Windows 10
  1. Click on Start
  2. Type PowerShell
  3. Select Windows PowerShell ISE
  4. Copy the script above
  5. Paste the code in the script section (you may need to expand it first, see red arrow)
  6. Change the path and make sure WhatIf is set to true first
  7. Click the green button to run the script.
Remove Empty Directories

Delete empty folders with RoboCopy

Another option to delete empty folders is to use RoboCopy. This command-line utility is built into Windows since Windows 7 and can be used in PowerShell or CMD.

The trick with RoboCopy is actually to move the directory to the same folder. The /S option copies all subdirectories but excludes the empty folders. Just make sure that you use the exact same path twice in RoboCopy.

# Make sure both paths are exactly the same
robocopy "c:\path\to\directory" "c:\path\to\directory" /S /move

If you first want to list all the empty directories with RoboCopy you can use the /L switch.

robocopy "c:\path\to\directory" "c:\path\to\directory" /S /move /L

Downside of using RoboCopy

There is one downside to using the RoboCopy method, it won’t remove empty directories with a Thumbs.db in it. This is a little file that is created by Windows in folders with images in it. You can safely remove this file if the directory is further empty.

With PowerShell we can ignore the file and remove it together with the empty directory. We can’t do such thing with RoboCopy.

How fast is RoboCopy with deleting empty folders?

delete empty folders

Robocopy was remarkable faster than PowerShell. Removing the 11.000 directories only took 4 secs on average.

Wrapping up

Always test script first, use the WhatIf mode, or run it on a couple of test folders so you are sure that it’s working as aspected.

The RoboCopy method is a lot faster then PowerShell, but keep in mind that it won’t remove directories with a Thumbs.db in it.

If you have any questions, just drop a comment below.

16 thoughts on “How to Remove Empty Directories with PowerShell, or Robocopy”

  1. thanks, but still not working !!, EG. i have a folder with 3 files contained 2x *.mrk and 1x *.Mrk. this does not have any .msg files so is actually empty, i need the script to force delete the folder if it ONLY has .mrk or Mrk files and no .msg.

    I actually got it working but had to bodge it by running attrib to change all of the .mrk files to HIDDEN, then run the function.

    attrib /s +H “d:\mdaemon\Users\jst.co.uk\$todo\Deleted Items.IMAP\*.mrk”
    attrib -H “d:\mdaemon\Users\jst.co.uk\$todo\Deleted Items.IMAP\*.mrk”
    Delete-EmptyFolder -path “e:\testdel”
    attrib /s -H “d:\mdaemon\Users\jst.co.uk\$todo\Deleted Items.IMAP\*.mrk”

    this works but a faff.

  2. hi, got this working on truely EMPTY folders but I need to have a folder that contains only certain extensions deleted too.

    E.G. I have a “deleted items.IMAP” folder on our email server that holds all my deleted messages and folders/subfolders. I have a script that correctly removes any old .msg files over 30 days but it is leaving the folders creating 1000’s.

    although these folders are empty of .msg files they all contain some special files used by the server, these have the extension of .mrk or .Mrk, i need the script to delete all folders that do NOT have any .msg files inside, and treat them as empty even if they still have the /mrk files inside.

    any ideas as yours has been the closest script ive found so far.

    thanks
    Steve

    • If you add an include filter to the Get-ChildItem cmdlet, it should work

      # Line 21
      $subItems = Get-ChildItem -Force:$getHiddelFiles -LiteralPath $path -Include ("*.msg")
      
  3. I know this is old…but I am getting Argument Exception with the remove command saying access to the path is denied at line 28

    • The script outputs the path of the empty folder that it is trying to delete. You can manually delete the folder in question? Because it looks like a permission issue.

  4. Hi,

    I’m trying to learn PS and had a quick question. Is there a way a good way to exclude multiple folder names with some type of array? The only way I could get it to work is by below. I need a bunch of exclusions so obviously my way is not an ideal method:

    # Get all child items
    $subItems = Get-ChildItem -Force:$getHiddelFiles -LiteralPath $path
    # If there are no items, then we can delete the folder
    If (($subItems -eq $null) -and (-Not($path.contains(‘exclusion1’) -and (-Not($path.contains(‘exclusion2’))))))
    #If ($subItems -eq $null)
    {
    Write-Host “Removing empty folder ‘${path}'”
    Remove-Item -Force -Recurse:$removeHiddenFiles -LiteralPath $Path -WhatIf:$whatIf
    }

    • Something like this, only it might be better to compare the path of the childitem. Don’t know where $path is coming from now…


      $exclusions = @(
      'exclusion1',
      'exclusion2'
      )

      # Get all child items
      $subItems = Get-ChildItem -Force:$getHiddelFiles -LiteralPath $path | Where-Object {$path -notin $exclusions}

      # If there are no items, then we can delete the folder
      If ($subItems -eq $null){
      Write-Host “Removing empty folder ‘${path}'”
      Remove-Item -Force -Recurse:$removeHiddenFiles -LiteralPath $Path -WhatIf:$whatIf
      }

  5. Hello,
    I know this is an old thread, but I would like to ask, as a complete newbie to powershell, if there is a way to getting the script to not delete, but hide all empty folders, and subfolders?

    Thank you

  6. Thank you very much for this PowerShell script example. I made an adjustment to speed up the processing for folder paths that have many thousands of subfolders. My example below also includes an exclusion statement for paths containing the string “.snapshot”. This excludes them from being tested for being empty.

    # Set to true to test the script
    $whatIf = $false

    # Remove hidden files, like thumbs.db
    $removeHiddenFiles = $false

    # Get hidden files or not. Depending on removeHiddenFiles setting
    $getHiddelFiles = !$removeHiddenFiles

    # Remove empty directories locally
    Function Delete-EmptyFolder($path)
    {
    # Go through each subfolder,
    $topleveldirectories = Get-ChildItem -Path $path -Directory -Force -ErrorAction SilentlyContinue | Select-Object FullName | Where-Object {($_.FullName -notlike “*.snapshot*”)}
    Foreach ($topleveldirectory in $topleveldirectories)
    {
    # Call the function recursively
    Delete-EmptyFolder -path $topleveldirectory.FullName
    }

    # Get all child items
    $subItems = Get-ChildItem -Force:$getHiddelFiles -LiteralPath $path

    # If there are no items, then we can delete the folder
    # Exlude folder: If (($subItems -eq $null) -and (-Not($path.contains(“DfsrPrivate”))))
    If ($subItems -eq $null)
    {
    Write-Host “Removing empty folder ‘${path}'”
    Remove-Item -Force -Recurse:$removeHiddenFiles -LiteralPath $Path -WhatIf:$whatIf
    }
    }

    # Run the script
    Delete-EmptyFolder -path “I:\”

  7. I want to thank you for the above. Very well done! Easy to understand and tailor. Wanted to share a small change I made to allow you to load a directory list from a file and run through that file until all items have been processed.
    When I run, I run this like this from Powershell terminal:

    ./script.ps1 >> logfile.txt
    RemoveEmptyDir_LIST.txt is the text file i created, and it’s as simple as a path per line.

    Thanks again!

    # Set to true to test the script
    $whatIf = $false
    # Remove hidden files, like thumbs.db
    $removeHiddenFiles = $true
    # Get hidden files or not. Depending on removeHiddenFiles setting
    $getHiddelFiles = !$removeHiddenFiles
    # Remove empty directories locally
    Function Delete-EmptyFolder($path)
    {
    # Go through each subfolder,
    Foreach ($subFolder in Get-ChildItem -Force -Literal $path -Directory)
    {
    # Call the function recursively
    Delete-EmptyFolder -path $subFolder.FullName
    }
    # Get all child items
    $subItems = Get-ChildItem -Force:$getHiddelFiles -LiteralPath $path
    # If there are no items, then we can delete the folder
    # Exluce folder: If (($subItems -eq $null) -and (-Not($path.contains("DfsrPrivate"))))
    If ($subItems -eq $null)
    {
    Write-Output "$(Get-Date) : Removing empty folder '${path}'"
    Remove-Item -Force -Recurse:$removeHiddenFiles -LiteralPath $Path -WhatIf:$whatIf
    }
    }
    # Run the script - ### added the load from text file section below.
    $collection = Get-Content c:\PS_Scripts\RemoveEmptyDir_LIST.txt
    ForEach ($item in $collection) {if (Test-Path $item) { try { Delete-EmptyFolder -path $item } catch {throw $_.Exception.Message }}
    else
    { Write-Output "$(Get-Date) : ERROR - Path does not exist: '${item}'" } }

  8. Hello, your script delete also the fist directory….
    Example :
    C:\TEST\TEST_J-7\xxxxxxxx
    I need preserve TEST_J-7 directory
    even if it remains empty. it is only the subdirectories that I want to delete.

  9. Why not just do this with Robocopy ?

    Of course, it does not do a “WhatIf” and also thumbs.db are not included now, but it does the trick in most cases:

    ROBOCOPY folder1 folder1 /S /MOVE

  10. Need to remove # in front of remove-Item for this to work, not made clear above, once that’s done, worked a treat, thanks

Leave a Comment

0 Shares