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