Prof. Powershell

All Together Now

Quickly check out all your object collections with the Group-Object cmdlet.

By now it has been repeatedly drilled into your head that PowerShell is object oriented. PowerShell cmdlets are designed to write collections of objects to the pipeline. They might be service, process or event log objects. They might even be objects of different types, but for our purpose this time, we'll assume they are all the same. The Group-Object cmdlet will examine an object collection and group them based on a specified property. Here's an example. First, run this command:

PS C:\> get-wmiobject win32_service

You will get a listing of all service objects from WMI. But perhaps you'd like to see the objects grouped together by start mode. Take the original expression and pipe it to Group-Member specifying the StartMode property:

PS C:\> get-wmiobject win32_service | group startmode

Count Name Group
----- ---- -----
80    Manual     {AcrSch2Svc, ALG, Appinfo, AppMgmt...}
56    Auto       {AeLookupSvc, AudioEndpointBuilder,
                  Audiosrv, avg8wd...}
23    Disabled   {AgereModemAudio, CertPropSvc,
                  CscService, ehRecvr...}


The Group-Object cmdlet creates a new object type, GroupInfo which is a collection of arrays based on the specified property. In this example there are 3 objects with properties of Count, Name and Group. Using Group-Object is a quick and dirty way to get an object count for certain types of objects. Let's look at one more example:

PS C:\> get-process | group-object company

Count   Name                 Group
-----   ----                 -----
1  AuthenTec, Inc.           {ATSwpNav}
3                            {audiodg, Idle, System}
3  AVG Technologies CZ, s... {avgrsx, avgtray, avgwdsvc}
6  Logitech Inc.             {COCIManager,                               Communications_Helper,
                              LVComSer, LVComSer...}
46 Microsoft Corporation     {csrss, csrss, dwm, ehmsas...}
2                            {DVD43_Tray, OSCM3}
1  Mozilla Corporation       {firefox}
3  Fujitsu Computer Syste... {FjDspMon, FjEvents, FjMnuIco}
1  FUJITSU LIMITED           {FUJ02E3}
1  Google                    {GoogleCalendarSync}
4  Intel Corporation         {hkcmd, igfxext, igfxpers,
                             igfxsrvc}
6  VMware, Inc.              {hqtray, vmnat, vmnetdhcp,
                              vmount2...}
1  Sun Microsystems, Inc.    {jusched}
1  O2Micro International     {o2flash}
1  Sprint Spectrum, L.L.C    {OSCMUtilityService}
1  Sysinternals              {procexp}
1  RealNetworks, Inc.        {realsched}
4  Acronis                   {schedhlp, schedul2,
                              TimounterMonitor,                               TrueImageMonitor}
1  Safer Networking Ltd.     {SDWinSec}
3  TechSmith Corporation     {SnagIt32, SnagPriv, TscHelp}
1  Synaptics, Inc.           {SynTPEnh}
1  Safer Networking Limited  {TeaTimer}
4  TOSHIBA CORPORATION.      {TosA2dp, TosBtHid,
                              TosBtHSP, TosBtMng}
1  Alexander Roshal {WinRAR}

This gives me a nice list of processes grouped by company name. But notice the list isn't as orderly as you might like it. It's not sorted. There are two solutions here. Either sort the process collection first:

PS C:\> get-process | sort company | group-object company

Or sort the group collection:

PS C:\> get-process | group-object company | sort name

You'll end up with the same result in either event. But what can you do with this?

First, let's save the results to a variable:

PS C:\> $companies=get-process | sort company | group-object company

How many companies are there?

PS C:\> $companies.count
23

Remember, $companies is not a list of processes but a list of groupings. You could use this variable to list all processes that belong to a specific company:

PS C:\> ($companies | where {$_.name -match "Intel"}).group | Select Name,Path,StartTime

Name     Path                             StartTime
----     ----                             ---------
igfxext  C:\Windows\system32\igfxext.exe  8/4/2008 7:15:16 AM
igfxpers C:\Windows\System32\igfxpers.exe 8/4/2008 7:14:53 AM
igfxsrvc C:\Windows\system32\igfxsrvc.exe 8/4/2008 7:15:16 AM
hkcmd    C:\Windows\System32\hkcmd.exe    8/4/2008 7:14:52 AM

Bet that surprised you. While $companies doesn't look like it has processes, it actually still does. All you have to do is unwrap them from the grouping object. Next time I'll show you another way to group objects.

About the Author

Jeffery Hicks is an IT veteran with over 25 years of experience, much of it spent as an IT infrastructure consultant specializing in Microsoft server technologies with an emphasis in automation and efficiency. He is a multi-year recipient of the Microsoft MVP Award in Windows PowerShell. He works today as an independent author, trainer and consultant. Jeff has written for numerous online sites and print publications, is a contributing editor at Petri.com, and a frequent speaker at technology conferences and user groups.

comments powered by Disqus
Most   Popular