Microsoft

Blog Categories

Subscribe to RSS feed

Archives

PowerShell: Count Property Returns Nothing

I was working on a a PowerShell script the other day and needed to do something I’ve done many times before with no trouble: count the items in a directory. In the past, I’ve gone about this in one of two ways:

  1. (Get-Item $Directory).GetFiles().Count
  2. (Get-ChildItem $Directory).Count

For this particular solution, I needed the number of files in the child directories as well, so I opted for Get-ChildItem as Get-Item doesn’t have a recurse parameter. I tested this in a very basic script on a directory with no subdirectories and, to my surprise, it didn’t work. It returned absolutely nothing—not zero, just nothing. I could see a file in the directory, and the Get-Item approach returned the appropriate count, so what was the problem?

Well, it turns out that this is a quirk caused precisely because there was only one file in the directory. Some searching revealed that in this case, PowerShell returns a scalar object instead of an array. This object doesn’t have a count property, so there isn’t anything to retrieve. You can verify this by passing your object into the Get-Member cmdlet:

Get-ChildItem $Directory | Get-Member –memberType property

.ExternalClass690B0634577744CA99F0D12F7F06D4CF .csharpcode, .ExternalClass690B0634577744CA99F0D12F7F06D4CF .csharpcode pre
{font-size:small;color:black;font-family:consolas, “Courier New”, courier, monospace;background-color:#ffffff;}
.ExternalClass690B0634577744CA99F0D12F7F06D4CF .csharpcode pre
{margin:0em;}
.ExternalClass690B0634577744CA99F0D12F7F06D4CF .csharpcode .rem
{color:#008000;}
.ExternalClass690B0634577744CA99F0D12F7F06D4CF .csharpcode .kwrd
{color:#0000ff;}
.ExternalClass690B0634577744CA99F0D12F7F06D4CF .csharpcode .str
{color:#006080;}
.ExternalClass690B0634577744CA99F0D12F7F06D4CF .csharpcode .op
{color:#0000c0;}
.ExternalClass690B0634577744CA99F0D12F7F06D4CF .csharpcode .preproc
{color:#cc6633;}
.ExternalClass690B0634577744CA99F0D12F7F06D4CF .csharpcode .asp
{background-color:#ffff00;}
.ExternalClass690B0634577744CA99F0D12F7F06D4CF .csharpcode .html
{color:#800000;}
.ExternalClass690B0634577744CA99F0D12F7F06D4CF .csharpcode .attr
{color:#ff0000;}
.ExternalClass690B0634577744CA99F0D12F7F06D4CF .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClass690B0634577744CA99F0D12F7F06D4CF .csharpcode .lnum
{color:#606060;}

Still, I wasn’t satisfied. Why was this working for Get-Item.GetFiles()? Shouldn’t that return a lone object too? I’m sure you’ve figured out by now that the answer is a resounding “No.” Get-ChildItem returns some form of an object no matter what—either a single System.IO.FileInfo or an array of System.Object. GetFiles(), on the other hand, always returns a string array—specifically, the file paths. If there’s only one object, it doesn’t care; it just returns an array of size 1. Of course, I can’t just throw GetFiles() onto the object returned by Get-ChildItem because System.IO.FileInfo doesn’t contain that method.

Fortunately, you can force PowerShell to return an array:

@(Get-ChildItem $Directory).Count
.ExternalClass690B0634577744CA99F0D12F7F06D4CF .csharpcode, .ExternalClass690B0634577744CA99F0D12F7F06D4CF .csharpcode pre
{font-size:small;color:black;font-family:consolas, "Courier New", courier, monospace;background-color:#ffffff;}
.ExternalClass690B0634577744CA99F0D12F7F06D4CF .csharpcode pre
{margin:0em;}
.ExternalClass690B0634577744CA99F0D12F7F06D4CF .csharpcode .rem
{color:#008000;}
.ExternalClass690B0634577744CA99F0D12F7F06D4CF .csharpcode .kwrd
{color:#0000ff;}
.ExternalClass690B0634577744CA99F0D12F7F06D4CF .csharpcode .str
{color:#006080;}
.ExternalClass690B0634577744CA99F0D12F7F06D4CF .csharpcode .op
{color:#0000c0;}
.ExternalClass690B0634577744CA99F0D12F7F06D4CF .csharpcode .preproc
{color:#cc6633;}
.ExternalClass690B0634577744CA99F0D12F7F06D4CF .csharpcode .asp
{background-color:#ffff00;}
.ExternalClass690B0634577744CA99F0D12F7F06D4CF .csharpcode .html
{color:#800000;}
.ExternalClass690B0634577744CA99F0D12F7F06D4CF .csharpcode .attr
{color:#ff0000;}
.ExternalClass690B0634577744CA99F0D12F7F06D4CF .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClass690B0634577744CA99F0D12F7F06D4CF .csharpcode .lnum
{color:#606060;}

One little at sign, and all your counting-related troubles will melt away.

Tags:

Leave a Reply