I was reading this post here: https://stackoverflow.com/a/28637537/800592
one of the comments mentions in order to not delete the root folder to do
@bricktop if ($IsEmpty) { # only remove if it is not the root if ($Path -ne $InPath) { Write-Output ">> Deleting empty folder ${InPath}" Remove-Item -Force -LiteralPath $InPath } }
BUT there's no where that sets the $InPath
var ?? what am I missing here ?
CodePudding user response:
A simple solution adapted from the original answer is to pass a recursion-depth counter to the script block, which defaults to 0
and is incremented for every recursive call.
Thus, if the counter is 0
, you know that you're dealing with the original input path, and you can ignore the attempt to delete that path itself:
$tailRecursion = {
param(
[string] $LiteralPath,
[int] $Depth = 0 # Helper parameter for internal use that tracks the recursion depth.
)
# Recurse over subdirs.
foreach ($childDirectory in Get-ChildItem -Force -LiteralPath $LiteralPath -Directory) {
# Note the increment to the recursion depth with -Depth ($Depth 1)
& $tailRecursion -LiteralPath $childDirectory.FullName -Depth ($Depth 1)
}
$isEmpty = -not (Get-ChildItem -Force -LiteralPath $LiteralPath | Select-Object -First 1)
if ($isEmpty -and $Depth -gt 0) { # dir. is empty and NOT the input dir.
Write-Verbose "Removing empty folder at path '${LiteralPath}'." -Verbose
Remove-Item -Force -LiteralPath $LiteralPath -WhatIf
}
}
# Sample call: delete all empty subdirs. in the current dir.'s
# subtree, without trying to delete the current dir itself,
# should it turn to be empty too.
& $tailRecursion -LiteralPath .
Note: The -WhatIf
common parameter in the command above previews the operation. Remove -WhatIf
once you're sure the operation will do what you want.
Note that this alternative answer to the same question provides the desired functionality directly, and more elegantly; the only downside - which will rarely matter in practice - is increased memory consumption due to the up-front sorting of all directory-info objects.
Here's a slightly tweaked version:
# Uses . (the current dir.) as the sample input path.
Get-ChildItem -LiteralPath . -Recurse -Force -Directory |
Sort-Object -Property FullName -Descending |
Where-Object { -not ($_ | Get-ChildItem -Force | Select-Object -First 1) } |
Remove-Item -WhatIf
Note: The -WhatIf
common parameter in the command above previews the operation. Remove -WhatIf
once you're sure the operation will do what you want.