134 lines
4.0 KiB
PowerShell
134 lines
4.0 KiB
PowerShell
<#
|
|
.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
|
|
|
|
} |