[powershell] How to count objects in PowerShell?

As I'm reading in the PowerShell user guide, one of the core PowerShell concepts is that commands accept and return objects instead of text. So for example, running get-alias returns me a number of System.Management.Automation.AliasInfo objects:

PS Z:\> get-alias

CommandType     Name                                             Definition
-----------     ----                                             ----------
Alias           %                                                ForEach-Object
Alias           ?                                                Where-Object
Alias           ac                                               Add-Content
Alias           asnp                                             Add-PSSnapIn
Alias           cat                                              Get-Content
Alias           cd                                               Set-Location
Alias           chdir                                            Set-Location
...

Now, how do I get the count of these objects?

This question is related to powershell scripting

The answer is


Just use parenthesis and 'count'. This applies to Powershell v3

(get-alias).count

As short as @jumbo's answer is :-) you can do it even more tersely. This just returns the Count property of the array returned by the antecedent sub-expression:

@(Get-Alias).Count

A couple points to note:

  1. You can put an arbitrarily complex expression in place of Get-Alias, for example:

    @(Get-Process | ? { $_.ProcessName -eq "svchost" }).Count
    
  2. The initial at-sign (@) is necessary for a robust solution. As long as the answer is two or greater you will get an equivalent answer with or without the @, but when the answer is zero or one you will get no output unless you have the @ sign! (It forces the Count property to exist by forcing the output to be an array.)

2012.01.30 Update

The above is true for PowerShell V2. One of the new features of PowerShell V3 is that you do have a Count property even for singletons, so the at-sign becomes unimportant for this scenario.


in my exchange the cmd-let you presented did not work, the answer was null, so I had to make a little correction and worked fine for me:

@(get-transportservice | get-messagetrackinglog -Resultsize unlimited -Start "MM/DD/AAAA HH:MM" -End "MM/DD/AAAA HH:MM" -recipients "[email protected]" | where {$_.Event
ID -eq "DELIVER"}).count

@($output).Count does not always produce correct results. I used the ($output | Measure).Count method.

I found this with VMware Get-VmQuestion cmdlet:

$output = Get-VmQuestion -VM vm1
@($output).Count

The answer it gave is one, whereas

$output

produced no output (the correct answer was 0 as produced with the Measure method).

This only seemed to be the case with 0 and 1. Anything above 1 was correct with limited testing.