I have a PowerShell 2.0 script that I use to delete folders that have no files in them:
dir 'P:\path\to\wherever' -recurse | Where-Object { $_.PSIsContainer } | Where-Object { $_.GetFiles().Count -eq 0 } | foreach-object { remove-item $_.fullname -recurse}
However, I noticed that there were a ton of errors when running the script. Namely:
Remove-Item : Directory P:\path\to\wherever cannot be removed because it is not empty.
"WHAT?!" I panicked. They should all be empty. I filter for only empty folders, Apparently that's not quite how the script is working: In this scenario a folder that has only folders as children, but files as grandchildren is considered empty of files:
Folder1 (no files - 1 folder) \ Folder 2 (one file)
In that case, PowerShell sees Folder1 as being empty and tries to delete it. The reason this puzzles me is because if I right-click on Folder1 in Windows Explorer It says that Folder1 has 1 folder and 1 file within it. Whatever is used to calculate the child objects underneath Folder1 from within Explorer allows it to see grandchild objects ad infinitum.
How can I make my script not consider a folder empty if it has files as grandchildren or beyond?
Updating for recursive deletion:
You can use a nested pipeline like below:
dir -recurse | Where {$_.PSIsContainer -and `
@(dir -Lit $_.Fullname -r | Where {!$_.PSIsContainer}).Length -eq 0} |
Remove-Item -recurse -whatif
(from here - How to delete empty subfolders with PowerShell? )
Add a ($_.GetDirectories().Count -eq 0)
condition too:
dir path -recurse | Where-Object { $_.PSIsContainer } | Where-Object { ($_.GetFiles().Count -eq 0) -and ($_.GetDirectories().Count -eq 0) } | Remove-Item
Here is a more succinct way of doing this though:
dir path -recurse | where {!@(dir -force $_.fullname)} | rm -whatif
Note that you do not need the Foreach-Object
while doing remove item. Also add a -whatif
to the Remove-Item
to see if it is going to do what you expect it to.
Here's a recursive function I used in a recent script...
function DeleteEmptyDirectories {
param([string] $root)
[System.IO.Directory]::GetDirectories("$root") |
% {
DeleteEmptyDirectories "$_";
if ([System.IO.Directory]::GetFileSystemEntries("$_").Length -eq 0) {
Write-Output "Removing $_";
Remove-Item -Force "$_";
}
};
}
DeleteEmptyDirectories "P:\Path\to\wherever";
There were some issues in making this script, one of them being using this to check if a folder is empty:
{!$_.PSIsContainer}).Length -eq 0
However, I discovered that empty folders are not sized with 0 but rather NULL. The following is the PowerShell script that I will be using. It is not my own. Rather, it is from PowerShell MVP Richard Siddaway . You can see the thread that this function comes from over at this thread on PowerShell.com .
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
You can use a recursive function for this. I actually have already written one:
cls
$dir = "C:\MyFolder"
Function RecurseDelete()
{
param (
[string]$MyDir
)
IF (!(Get-ChildItem -Recurse $mydir | Where-Object {$_.length -ne $null}))
{
Write-Host "Deleting $mydir"
Remove-Item -Recurse $mydir
}
ELSEIF (Get-ChildItem $mydir | Where-Object {$_.length -eq $null})
{
ForEach ($sub in (Get-ChildItem $mydir | Where-Object {$_.length -eq $null}))
{
Write-Host "Checking $($sub.fullname)"
RecurseDelete $sub.fullname
}
}
ELSE
{
IF (!(Get-ChildItem $mydir))
{
Write-Host "Deleting $mydir"
Remove-Item $mydir
}
}
}
IF (Test-Path $dir) {RecurseDelete $dir}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.