Discover Group-Object

by Oct 9, 2018

Group-Object is an awesome cmdlet: it can easily visualize distributions. Check out the examples below:

Get-Process | Group-Object -Property Company Get-Eventlog -LogName System -EntryType Error | Group-Object -Property Source Get-ChildItem -Path c:\windows -File | Group-Object -Property Extension

Basically, the cmdlet builds groups based on the content of a given property. You can also omit the group, and just look at the count if all that matters to you are the number distributions:

 PS C:\> Get-ChildItem -Path c:\windows -File | Group-Object -Property Extension -NoElement | Sort-Object -Property Count -Descending Count Name ----- ---- 10 .exe 10 .log 5 .ini 4 .xml 3 .dll 2 .txt 1 .dat 1 .bin 1 .tmp 1 .prx

If you are more interested in the actual group of objects, you can ask Group-Object to return a hash table. This way, you can access individual groups via their key:

$hash = Get-ChildItem -Path c:\windows -File | Group-Object -Property Extension -AsHashTable $hash.'.exe'

The result dumps all files in the Windows folder with “.exe” extension. Just be careful if the key (the property you are asking for) is not a string.

Likewise, if you use PowerShell remoting and fan out to multiple computers to retrieve information in parallel, Group-Object can group the results again once you received them. This example retrieves the services from three computers simultaneously, and the results can come back to you in any random order. Group-Object groups the incoming data so that you can process the results per computer. As always with hash tables, you can use brackets or dots to access the hash table keys:

$services = Invoke-Command -ScriptBlock { Get-Service } -ComputerName server1, server2, server3 | Group-Object -Property PSComputerName -AsHashTable $services["server1"] $services."server2"

Here is a similar example that seems to have a bug – can you spot the error?

$hash = Get-Service | Group-Object -Property Status -AsHashTable $hash.'Running'

When you look at the hash table, you would expect to get back the running services:

 PS C:\> $hash Name Value ---- ----- Running {AdobeARMservice, AGMService, AGSService, App... Stopped {AJRouter, ALG, AppIDSvc, AppMgmt...}

However, you don’t get back anything. That’s because the key in this hash table is not a string but rather a “ServiceControllerStatus” object:

 PS C:\> $hash.Keys | Get-Member TypeName: System.ServiceProcess.ServiceControllerStatus

In order to get back accessible keys, you should always combine -AsHashTable with -AsString. The latter makes sure that a key is always turned into a string. Now the example works as expected:

$hash = Get-Service | Group-Object -Property Status -AsHashTable -AsString $hash.'Running'

Twitter This Tip! ReTweet this Tip!