3

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?)

DJDave
  • 865
  • 1
  • 13
  • 28
  • 2
    [This](https://www.petri.com/powershell-problem-solver-delete-empty-folders) is pretty nifty - `dir -Directory -recurse | where { -NOT $_.GetFiles()} | Select Fullname`. I have no idea why you are getting that error message though. – Lieven Keersmaekers Sep 18 '19 at 18:01
  • Thanks! - your empty condition works and I get just what I'm looking for (A and C/D but not B) when I plumb it in.. dir -Directory -recurse | Where-Object {$_.Name -eq "X" -and -NOT $_.GetFiles()} | Select-Object -ExpandProperty FullName – DJDave Sep 18 '19 at 18:27
  • 1
    As for why your attempts didn't work: `(Measure-Object).count` is always `0`, because you're not providing any input to `Measure-Object`. The error message stems from the fact that `$_` in `Get-ChildItem $_` - unfortunately - doesn't expand to the full path - use `Get-ChildItem $_.FullName` instead; as for why that happens: see https://stackoverflow.com/a/53400031/45375 – mklement0 Sep 19 '19 at 05:13
  • now I'm trying it in my live case I've had to add in -and -NOT $_.GetDirectories() – DJDave Sep 19 '19 at 09:37

3 Answers3

2

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]

Lee_Dailey
  • 7,292
  • 2
  • 22
  • 26
1

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."
}
Clev
  • 109
  • 9
1

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.

jrider
  • 1,571
  • 1
  • 10
  • 26
  • This doesn't work for me - I needed Lieven's condition to identify empty, but -ExpandProperty FullName is useful so I've added a point – DJDave Sep 18 '19 at 18:29