PowerShell function to remove empty folders from a given path, recursively. You may optionally exclude a list of matching paths from removal.
function Remove-EmptyFolders
{
<#
.SYNOPSIS
Removes empty folders recursively from a root directory.
The root directory itself is not removed.
.DESCRIPTION
PowerShell function to remove empty folders from a given path, recursively.
You may optionally exclude a list of matching paths from removal.
.EXAMPLE
PS > . .\Remove-EmptyFolders.ps1
Dot sources the PowerShell script and imports the Remove-EmptyFolders
function in the current session.
.EXAMPLE
PS > Remove-EmptyFolders -Path /some/posix/path
Remove empty folders from a POSIX path.
.EXAMPLE
PS > Remove-EmptyFolders -Path \\some\unc\path
Remove empty folders from a UNC path.
.EXAMPLE
PS > $pwd | Remove-EmptyFolders -WhatIf -Verbose -Exclude $('.git', 'node_modules')
Perform a Dry-run/WhatIf, and exclude attempting to remove empty folders
with '.git' and 'node_modules' in their path.
.NOTES
Authors: Joakim Borger Svendsen, Svendsen Tech, Jon LaBelle
Version: v1.1.0
Copyright (c) 2022 MIT License
.LINK
https://github.com/EliteLoser/misc/blob/master/PowerShell/Remove-EmptyFolders.ps1
.LINK
https://jonlabelle.com/snippets/view/powershell/remove-empty-folders-in-powershell
#>
[CmdletBinding(SupportsShouldProcess)]
param(
# A path to a location. Wildcards are accepted. The default location is the current directory (.).
[Parameter(
ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[ValidateNotNullOrEmpty()]
[String]
$Path = '.',
# Specifies an array of one or more string patterns to be matched as the cmdlet gets child items. Any matching item is excluded from the output. Enter a path element or pattern, such as *.txt or A*. Wildcard characters are accepted.
[Parameter()]
[String[]]
$Exclude = @()
)
begin
{
[Int32] $Script:Counter = 0
if (++$Counter -eq 1)
{
$RootPath = $Path
Write-Verbose -Message "Saved root path as '$RootPath'."
}
# Avoid overflow. Overly cautious?
if ($Counter -eq [Int32]::MaxValue)
{
$Counter = 1
}
}
process
{
# List directories.
foreach ($ChildDirectory in Get-ChildItem -LiteralPath $Path -Force -Exclude $Exclude |
Where-Object {$_.PSIsContainer})
{
# Use .ProviderPath on Windows instead of .FullName in order to support UNC paths (untested).
# Process each child directory recursively.
Remove-EmptyFolders -Path $ChildDirectory.FullName
}
$CurrentChildren = Get-ChildItem -LiteralPath $Path -Force
# If it's empty, the condition below evaluates to true.
# Get-ChildItem returns $null for empty folders.
if ($null -eq $CurrentChildren)
{
# Do not delete the root folder itself.
if ($Path -ne $RootPath)
{
if ($PSCmdlet.ShouldProcess($Path, 'Remove empty folder'))
{
Remove-Item -LiteralPath $Path -Force -WhatIf:$WhatIfPreference
}
}
}
}
}