<# .SYNOPSIS Svendsen Tech's generic script for removing empty directories from a directory tree structure. Finds or removes/deletes empty directories recursively from the drive or directory you specify. You will need to use the -VerifyNoEmpty parameter or multiple runs to get rid of nested empty directories. See the -VerifyNoEmpty parameter's description for further details. This isn't the most efficient approach as the ones I can think of seem to increase the script's complexity considerably. It should be useful for a multitude of use cases. Author: Joakim Svendsen .PARAMETER Path Required. Base root path to iterate recursively. .PARAMETER Find Default behaviour where it just prints. Overrides -Remove if both are specified. .PARAMETER Remove Removes all empty dirs (as in actually deletes them with Remove-Item). .PARAMETER VerifyNoEmpty Makes the script run until no empty directories are found. This is in order to handle nested empty directories, as in a directory that currently only contains an empty directory would be empty after the first run/iteration and need to be remove in a subsequent run. Specifying this parameter causes the script to run until it's done a complete run without finding a single empty directory. This might be time-consuming depending on the size of the directory tree structure. If there is an error while deleting a directory, it will not run again, to avoid an infinite loop. #> param( [Parameter(Mandatory=$true)][string] $Path, [switch] $Find, [switch] $Remove, [switch] $VerifyNoEmpty ) Set-StrictMode -Version 2.0 $ErrorLog = 'remove-empty-dirs-error.log' ######## START OF FUNCTIONS ######## function Iterate-And-Remove-Empty-Dirs { $FoundEmpty = $false Write-Host "Iterating '$Path'" Get-ChildItem -Force -Recurse -Path $Path | Where-Object { $_.PSIsContainer } | ForEach-Object { if ($Find -or -not $Remove) { if (-not (Get-ChildItem -Force $_.FullName)) { # Directory should be empty $_.FullName + ' is empty' } } # This is the dangerous part elseif ($Remove) { if (-not (Get-ChildItem -Force $_.FullName)) { $FoundEmpty = $true # Directory should be empty Remove-Item -Force $_.FullName if (-not $?) { Write-Host -ForegroundColor Red "Error: $(Get-Date): Unable to delete $($_.FullName): $($Error[0].ToString))" "Error: $(Get-Date): Unable to delete $($_.FullName): $($Error[0].ToString))" | Out-File -Append $ErrorLog $FoundEmpty = $false # avoid infinite loop } else { Write-Host -ForegroundColor Green "$(Get-Date): Successfully deleted the empty folder: $($_.FullName)" } } } } # end of ForEach-Object $FoundEmpty } # end of function Iterate-And-Remove-Empty-Dirs ######## END OF FUNCTIONS ######## if (-not (Test-Path -Path $Path -PathType Container)) { "The specified path does not exist. Exiting with code 1." exit 1 } if ($Remove -and $VerifyNoEmpty) { $Counter = 0 while (($OutsideFoundEmpty = Iterate-And-Remove-Empty-Dirs) -eq $true) { $Counter++ Write-Host -ForegroundColor Yellow "-VerifyNoEmpty specified. Found empty dirs on run no ${Counter}. Starting next run." } $Counter++ Write-Host "Made $Counter runs in total" } else { Iterate-And-Remove-Empty-Dirs }