# Delete all empty folders in a directory tree - oops, script deletes files too

#### rated by 0 users This post has 6 Replies | 4 Followers

Posts 6
Nonapeptide Posted: 08-12-2011 6:18 PM

I have a large folder that has both empty and full folders. I am using SBS 2008 and PowerShell 2.0. I used the following script (running from within the PowerShell ISE as an administrator) to recursively delete only empty folders:

dir 'P:\File Server\Cleanup\' -recurse |

Where { $_.PSIsContainer -and @(dir -Lit$_.Fullname -r | Where {!$_.PSIsContainer}).Length -eq 0 } | Remove-Item -recurse However, I noticed that before the script ran I had 17,832 folders and 232,343 files. After the script ran I had 12,622 folders and 201,286 files. Oops. Furthermore, I saw the following errors in the ISE which puzzled me: + Remove-Item <<<< -recurse + CategoryInfo: PermissionDenied: (desktop.ini:FileInfo) [Remove-Item], IOException + FullyQualifiedErrorId : RemoveFileSystemItemUnAuthorizedAccess,Microsoft.PowerShell.Commands.RemoveItemCommand Remove-Item: Directory P:\path\to\a\folder cannot be removed because it is not empty. Wait, WHAT? It's not supposed to even get to the point of attempting to delete a folder if it's not empty! 1. Why did files get deleted when it appears that the logic should have prevented that? 2. Why are deletions being attempted on folders with files in them? Thanks for your help! P.S. Are there no code blocks on these forums? I noticed that the code snippets look kinda ugly. Posts 5 SJHarper replied on 08-13-2011 11:53 AM Try this instead. gci "N:\test\" -r | ? {$_.PSIsContainer -eq $True} | ? {$_.GetFiles().Count -eq 0 -and $_.GetDirectories().Count -eq 0} | remove-item Steve Posts 296 RSiddaway replied on 08-13-2011 12:05 PM One problem is that if a folder contains zero length files the length is still zero but it has content The problem centres on this snippet (Get-ChildItem$_.Fullname -Recurse |  where {!$_.PSisContainer}).Length If the folder is empty the length isn't 0. No measurements can be taken so the length doesn't exist! Compare these two lines PS> (Get-ChildItem C:\test\test3 -Recurse | where {!$_.PSisContainer}).Length -eq 0
False

PS> (Get-ChildItem C:\test\test3 -Recurse |  where {!$_.PSisContainer}).Length -eq$null
True

The length of an empty folder is NULL not zero.

If you want to identify empty folders this is a much easier and safer way

$path = "c:\test"$fso = New-Object -ComObject "Scripting.FileSystemObject"

$folder =$fso.GetFolder($path) foreach ($subfolder in $folder.SubFolders){ if (($subfolder.Files | Measure-Object).Count -gt 0){continue}
if (($subFolders.SubFolders | Measure-Object).Count -gt 0){continue} if ($subfolder.Size -eq 0 ){Remove-Item -Path $($subfolder.Path) -Force -WhatIf}

}

BUT this doesn't work recursively so we need a bit of modification

function remove-emptyfolder {
param ($folder) foreach ($subfolder in $folder.SubFolders){$notempty = $false if (($subfolder.Files | Measure-Object).Count -gt 0){$notempty =$true}
if (($subFolders.SubFolders | Measure-Object).Count -gt 0){$notempty = $true} if ($subfolder.Size -eq 0 -and !$notempty){ Remove-Item -Path$($subfolder.Path) -Force -WhatIf } else { remove-emptyfolder$subfolder
}

}

}

$path = "c:\test"$fso = New-Object -ComObject "Scripting.FileSystemObject"

$folder =$fso.GetFolder($path) remove-emptyfolder$folder

Posts 6
Nonapeptide replied on 08-13-2011 6:58 PM

Wooow! Excellent! I'll give that a try when I get a chance. I didn't know that a zero length is different from a null. That makes sense now.

I have much more to learn about PowerShell. =)

Thanks for your time and effort!

Posts 6
Nonapeptide replied on 08-23-2011 5:01 PM

Just a quick checkin. When running this script, I receive the notification that "The item at c:\path\to\folder has children and the recurse parameter was not specified.. If you continue all children will be removed"

Interestingly, the folders that are throwing that interrupt have folders in them that are themselves completely empty. When I look through the script, my rudimentary skills seem to understand it as iterating down to the lowest leaves in the filesystem tree until it finds a folder that itself has absolutely nothing in it. When it finds a folder like that, it then removes it and goes up a level.

Certainly I can add the -recurse but I'm just wondering why the recursive function doesn't go down to the lowest levels and then work its way back up. There's definitely something I'm not understanding.

Posts 1
phpgen replied on 01-06-2012 11:17 AM

hii have u tried this tool ??

http://longpathtool.com

Posts 1
johnfrings replied on 10-08-2014 7:06 PM

I am aware that I'm replying to a rather old post but I just wanted to share my modifications. There is no -WhatIf in my version and it's not tested much so probably don't test it on any real folders...

What mainly differs is the ability to handle nested folders that become empty once their empty subfolder has been removed.

(I also made an attempt to allow passing a path as a string which will then automagically become a FSO folder but it lacks error handling etc)

function RemoveEmptyFoldersRecursive {

param ($folder) # Check if a string was passed and if so make it a FileSystemObject folder if ($folder.GetType().FullName -ne "System.__ComObject")

{

$fso = New-Object -ComObject "Scripting.FileSystemObject"$folder = $fso.GetFolder($folder)

RemoveEmptyFoldersRecursive $folder } else { if (($folder.SubFolders | Measure-Object).Count -gt 0) {

# recurse on subfolders if folder has subfolders

foreach ($subfolder in$folder.SubFolders) {

RemoveEmptyFoldersRecursive $subfolder } } # check again to see if the folder still contains anything if (($folder.SubFolders | Measure-Object).Count -eq 0) {

if (($folder.Files | Measure-Object).Count -eq 0 -and$folder.Size -eq 0) {

# remove folder if it is empty

Write-Host "Removing empty folder " $folder.Path Remove-Item -Path$(\$folder.Path) -Force

}

}

}

}

Page 1 of 1 (7 items) | RSS