I made a backup of all files with a certain pattern files from one directory to another. If the pattern was, say PostScript (*.ps) files, you can use the following PowerShell statement:
Copy-Item -recurse -filter *.ps <source> <destination>
Now I had a new directory with the same structure as the original one, but Copy-Item
made many new empty directories because there were files in the source directories but these files were not copied. Just to be tidy, I wanted to prune the empty directories in the destination path. The Remove-Item
cmdlet does not have an option to remove empty directories, so I wrote the following short PowerShell script:
1 function prune-directory { 2 param ([string]$path) 3 if ($path.Length -le 0) { 4 write-host "Empty path." 5 return 6 } 7 if (-not (test-path -literalPath $path)) { 8 write-host "Invalid path:", $path 9 return 10 } 11 if (@(get-childitem $path).Count -le 0) { 12 remove-item $path 13 return 14 } 15 get-childitem $path | where-object { $_.PsIsContainer} | foreach { prune-directory $_.FullName } 16 if (@(get-childitem $path).Count -le 0) { 17 remove-item $path 18 } 19 }
To use it, just enter:
prune-directory <path>
You should verify that the function works the way you expect before using it. Once your directories or files are deleted, they're GONE.
prune-directory()
is a recursive function that walks a directory tree and deletes any empty directory it finds. Lines 3-10 check for invalid parameters, lines 11-14 delete the current directory if it is empty and line 18 calls this function for all children which are containers in the current directory. Lines 19-22 are required in case the current directory has no children because they were all deleted by line 15.
In line 11 and 16, we use @(…)
to force the result of get-childitem $path
to be an array, otherwise we may not be able to count the number of children in a directory. It's a known - uh - nuance in PowerShell that if a cmdlet finds zero or one object, it returns an scalar value rather than an array.
2008-05-15: This change should fix the problem of escape characters in the path string: test-path -literalPath $path
.
This chokes on file names containing square brackets
ReplyDelete(like my itunes folder)
Eg
"+ if (-not (test-path <<<< $path)) {
Get-ChildItem : Cannot retrieve the dynamic parameters for the cmdlet. The specified wildcard pattern is not valid: Min
istry of Sound_ The 2005 Annual [EMI"
In order to avoid troubles with 'strange' folder names you can replace the test test-path $path with [IO.Directory]::exists($path)
ReplyDelete