Last active
December 23, 2024 23:22
-
-
Save sba923/571e7b02bddab9c587ee97110b898629 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# this is one of Stéphane BARIZIEN's public domain scripts | |
# the most recent version can be found at: | |
# https://gist.github.com/sba923/571e7b02bddab9c587ee97110b898629#file-remove-emptydirectories-ps1 | |
param([string] $Path, [switch] $IgnoreSystemFiles, [switch] $torecyclebin, [switch] $ContinueOnErrors) | |
if (!(Test-Path -Path $Path)) | |
{ | |
throw("'{0}' not found" -f $Path) | |
} | |
Set-StrictMode -Version 2.0 | |
$VerbosePreference = 'Continue' | |
$systemfiles = @('thumbs.db', 'desktop.ini', 'PPMetaData.bin', '.ppinfocache', 'ZbThumbnail.info', 'PCM.db') | |
# derived from http://stackoverflow.com/questions/502002/how-do-i-move-a-file-to-the-recycle-bin-using-powershell | |
Add-Type -AssemblyName Microsoft.VisualBasic | |
function Remove-Item-ToRecycleBin($Path) | |
{ | |
$item = Get-Item -Path $Path -ErrorAction SilentlyContinue | |
if ($null -eq $item) | |
{ | |
Write-Error("'{0}' not found" -f $Path) | |
} | |
else | |
{ | |
$fullpath = $item.FullName | |
Write-Verbose ("Moving '{0}' to the Recycle Bin" -f $fullpath) | |
if (Test-Path -LiteralPath $fullpath -PathType Container) | |
{ | |
[Microsoft.VisualBasic.FileIO.FileSystem]::DeleteDirectory($fullpath, 'OnlyErrorDialogs', 'SendToRecycleBin') | |
} | |
else | |
{ | |
[Microsoft.VisualBasic.FileIO.FileSystem]::DeleteFile($fullpath, 'OnlyErrorDialogs', 'SendToRecycleBin') | |
} | |
} | |
} | |
function IsEmptyOrContainsOnlySystemFiles([string] $Path, [switch] $IgnoreSystemFiles) | |
{ | |
$contents = (Get-ChildItem -Force -LiteralPath $Path | Where-Object { (!$IgnoreSystemFiles) -or ($_.Name -notin $systemfiles) }) | |
if ($null -eq $contents) | |
{ | |
return $true | |
} | |
else | |
{ | |
if ($contents.GetType().Name -match '(File|Directory)Info') | |
{ | |
return $false | |
} | |
else | |
{ | |
return($contents.Count -eq 0) | |
} | |
} | |
} | |
function Remove-EmptyDirectories([string] $Path, [switch] $IgnoreSystemFiles, [switch] $torecyclebin) | |
{ | |
Write-Debug ("Processing subdirectories within '{0}'" -f $Path) | |
try | |
{ | |
Get-ChildItem -Force -Directory -LiteralPath $Path | Foreach-Object { | |
Remove-EmptyDirectories -path $_.FullName -ignoresystemfiles:$IgnoreSystemFiles -torecyclebin:$torecyclebin | |
} | |
if (IsEmptyOrContainsOnlySystemFiles -path $Path -ignoresystemfiles:$IgnoreSystemFiles) | |
{ | |
$contents = Get-ChildItem -Force -Recurse -LiteralPath $Path | |
if ($null -eq $contents) | |
{ | |
Write-Debug ("Removing empty directory '{0}'" -f $Path) | |
} | |
else | |
{ | |
Write-Debug ("Removing '{0}' with the following contents:" -f $Path) | |
$contents | ForEach-Object { | |
Write-Debug("{0}" -f $_.FullName) | |
} | |
} | |
if ($torecyclebin) | |
{ | |
Remove-Item-ToRecycleBin -Path $Path | |
} | |
else | |
{ | |
Remove-Item -Force -Recurse -Verbose -LiteralPath $Path -ErrorAction SilentlyContinue | |
# retry without -Force if failed with -Force | |
if (Test-Path -LiteralPath $Path) | |
{ | |
Remove-Item -Recurse -Verbose -LiteralPath $Path | |
if (!$? -and !$ContinueOnErrors) | |
{ | |
Exit(1) | |
} | |
} | |
} | |
} | |
else | |
{ | |
Write-Debug("'{0}' is NOT empty" -f $Path) | |
} | |
} | |
catch | |
{ | |
Write-Error ("EXCEPTION: " + $_) | |
} | |
} | |
if (-not $PSBoundParameters.ContainsKey('Path')) # testing (typically: running via F5 under ISE) | |
{ | |
$DebugPreference = 'Continue' | |
# create test data | |
$testroot = $env:TEMP + '\a' | |
Remove-Item -Force -Recurse -LiteralPath $testroot -ErrorAction SilentlyContinue | |
mkdir $testroot | Out-Null | |
mkdir "$testroot/b" | Out-Null | |
mkdir "$testroot/c" | Out-Null | |
mkdir "$testroot/c/d" | Out-Null | |
"foo" | out-file "$testroot/c/d/file_in_d" | |
mkdir "$testroot/b/e" | Out-Null | |
mkdir "$testroot/b/e/f" | Out-Null | |
mkdir "$testroot/b/e/f/g" | Out-Null | |
"foo" | Out-File -FilePath "$testroot/b/e/f/g/thumbs.db" | |
"foo" | Out-File -FilePath "$testroot/b/e/thumbs.db" | |
"foo" | Out-File -FilePath "$testroot/b/e/file_in_e" | |
Remove-EmptyDirectories -path $testroot -ignoresystemfiles:$true -torecyclebin:$true | |
if (Test-Path -LiteralPath $testroot) | |
{ | |
Invoke-Item -LiteralPath $testroot | |
} | |
else | |
{ | |
Write-Host -Object ("'{0}' has been completely removed" -f $testroot) | |
} | |
} | |
else | |
{ | |
Remove-EmptyDirectories -path $Path -ignoresystemfiles:$IgnoreSystemFiles -torecyclebin:$torecyclebin | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment