DJDave
DJDave

Reputation: 915

how do I find all empty directories with a given name using Powershell?

I want to use Powershell to find all empty directories within a file structure that are called "Information & Specification". I thought I had cracked it when this line

dir -Directory -recurse | Where-Object {$_.Name -eq "Information & Specification" -and (Measure-Object).count -eq 0} | Select-Object -Property Parent

started returning results. However, it looks like it finds all "Information & Specification" folders irrespective of whether they have files in or not - if I reverse the count condition from -eq to -ne I get nothing.

So I set up a simple test hierachy with folders A, B, C at top level. A and B both contain a folder called X. (I am going to search for X rather than "Information & Specification" in my test). Folder C contains folder D, and D contains a folder called X.

I ran

dir -Directory -recurse | Where-Object {$_.Name -eq "X" -and (Measure-Object).count -eq 0} | Select-Object -Property Parent

and got

Parent
......
A
B
D

which appeared correct. But when I created a file in the B/X folder, I still got the same result, so clearly my test for emptiness is wrong. I referred back to Count items in a folder with PowerShell and tried

dir -Directory -recurse | Where-Object {$_.Name -eq "X" -and (Get-ChildItem $_ | Measure-Object).count -eq 0} | Select-Object -Property Parent

but this yields an error message I do not understand

Get-ChildItem : Cannot find path 'C:\temp\search_test\X' because it does not exist.

Can anyone help with the test for emptiness (or an entirely alternative solution?)

Upvotes: 3

Views: 559

Answers (3)

jrider
jrider

Reputation: 1640

This will give you the FullName of all empty directories under C:\Test:

Get-ChildItem -Path "C:\Test" -Directory -Recurse | Where-Object -FilterScript {($_.GetFiles().Count -eq 0) -and ($_.GetDirectories().Count -eq 0) -and $_.Name -eq "Information & Specification"} | Select-Object -ExpandProperty FullName

From here you can do handle the results anyway you want.

Upvotes: 1

Lee_Dailey
Lee_Dailey

Reputation: 7479

this uses the .GetFileSystemInfos() method of a directory to get any subdirs AND any files. the output is the list of directory full names. if you want the objects, remove the final .FullName. [grin]

$TopDir = 'D:\Temp'
$DirToFind = 'Sample'

$EmptyDirList = @(
    Get-ChildItem -LiteralPath $TopDir -Directory -Recurse |
        Where-Object {
            #[System.IO.Directory]::GetFileSystemEntries($_.FullName).Count -eq 0
            $_.GetFileSystemInfos().Count -eq 0 -and
            $_.Name -match $DirToFind
            }
        ).FullName

$EmptyDirList

truncated output ...

D:\Temp\zzz - Copy\Destination\DEcho\Music\Sample Music
D:\Temp\zzz - Copy\Destination\DEcho\Pictures\Sample Pictures
D:\Temp\zzz - Copy\Destination\DEcho\Videos\Sample Videos

[*...snip...*] 

D:\Temp\zzz - Copy\Users - Copy\Admin\Music\Sample Music
D:\Temp\zzz - Copy\Users - Copy\Admin\Pictures\Sample Pictures
D:\Temp\zzz - Copy\Users - Copy\Admin\Videos\Sample Videos

all of those dirs are empty. [grin]

Upvotes: 2

Clev
Clev

Reputation: 109

The easiest way to get a count is to assign the get-childitem to a variable then .count that variable. Such as:

$fileCount = get-childitem "C:\temp\search_test\X'
if ($fileCount.count -gt 0)
{
Write-Host "Files found!"
}
else
{
Write-Host "No files found."
}

Upvotes: 1

Related Questions