Use PowerShell to Group and Format Output

Use PowerShell to Group and Format Output

  • Comments 5
  • Likes

Summary: Microsoft Scripting Guy, Ed Wilson, teaches how to use Windows PowerShell to group and to format output.

Microsoft Scripting Guy, Ed Wilson, is here. One of the cool things about Windows PowerShell is that it allows you to work the way that you like to do so. The other day, I was making a presentation to the Charlotte PowerShell Users Group. The photo that follows shows me talking, and the Scripting Wife and Microsoft PFE Jason Walker at this first ever meeting.

Photo

One of the attendees asked, “Is Windows PowerShell a developer technology or a network administrator type of technology?” Before I could even answer the question, someone else jumped in and said that Windows PowerShell is really powerful, and that it has a number of things that would appeal to developers. However, he continued, the main thing about Windows PowerShell is that it allows you to process large amounts of data very quickly. Cool, I thought to myself; I did not see the need to add anything else to the conversation.

One of the fundamental aspects of working with data is grouping the data to enable viewing relationships in a more meaningful way. Earlier this week, I looked at using the Group-Object cmdlet to group information.

The Group-Object cmdlet does a good job of grouping Windows PowerShell objects for display, but there are times when a simple grouping might be useful in a table. The problem is that the syntax is not exactly intuitive. For example, it would seem that the command that is shown here would work.

Get-Service | Format-Table name, status -GroupBy status

When the command runs, however, the output (shown in the following image) appears somewhat jumbled.

Image of command output

In fact, the first time I ran across this, the output confused me because it looks like it is grouping the output. The second time I ran across this grouping behavior, the output seriously disappointed me because I realized that it was not really grouping the output. Then it dawned on me, I need to sort the output prior to sending it to the Format-Table command. I therefore, modified the command to incorporate the Sort-Object cmdlet. The revised command is shown here.

Get-Service | Sort-Object status | Format-Table name, status -GroupBy status

After it is sorted by the Status property, the service information displays correctly in the grouped table. This revised output is shown in the image that follows.

Image of command output

As might be expected, this non-grouping behavior also exists with the Format-List cmdlet, which is a cmdlet that also contains the GroupBy parameter. The code that follows appears to group the output, until one takes a closer look at the output.

Get-Service | Format-List name, status -GroupBy status

A look at the output (shown in the following image) shows that the grouping occurs only when concurrent services share the same status.

Image of command output

The fix for the grouped output from the Format-List cmdlet is the same as the fix for the Format-Table cmdlet—first sort the output by using the Sort-Object cmdlet, then pipe the sorted service objects to the Format-List cmdlet for grouping. The revised code is shown here.

Get-Service | sort-object status | Format-List name, status -GroupBy status

The revised command and the associated sorted output from the command are shown in the image that follows.

Image of command output

One of the cool things to do with the Format-List cmdlet is to use a ScriptBlock in the GroupBy parameter. Once again, it is necessary to sort the output prior to sending it to the Format-List cmdlet. In fact, you may need to sort on more than one parameter, as illustrated in the code that follows. (This code is a single line command that is broken at the pipe character for readability).

Get-Service | sort-object status, canstop |

Format-List name, status –GroupBy {$_.status -eq 'running' -AND $_.canstop}

To make the output easier to assess, I added the Unique switched parameter to the Sort-Object cmdlet to shorten the output. Interestingly enough, the first condition reports two services for the first condition. This is because each -AND combination equals False.

Image of command output

Format-Table also accepts a ScriptBlock for the GroupBy parameter. It works the same way that the Format-List behaves. The code that follows creates two tables, one that evaluates to False, and one that evaluates to True.

Get-Service | sort-object status, canstop -unique |

Format-table name, canstop, status -GroupBy {$_.status -eq 'running' -AND $_.canstop}

The image that follows illustrates creating a table that groups output based on a ScriptBlock.

Image of command output

Well, that is about all there is to grouping output information by using the Format-Table and the Format-List cmdlets.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy 

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Useful:

    Fully sorted list:

    Get-Service | sort-object status,name | Format-List name -GroupBy status

  • Hi Ed,

    again something for the daily work toolbox!

    And again using script blocks increases the flexibility of "Goupby" a lot!

    Klaus (Schulte)

  • This is just what I was looking for.

    One more thing I would like, how would I add a total as a summary.

    I'm trying to output a table showing all the computers in AD along with their OS. I then want it grouped by OS and give me a total value for each (e.g. 700xXP, 300xWin7). Is that possible?

  • Hi,

    I have been searching for a way to split an ordered set of columns across the screen and I found none. I hear Powershell is the thing now so I hope it can be done.

    Here what I want

    Key         Value

    ----         -------

    C              1

    A              2

    D              3

    I'd like the above to look like this instead

    Key         Value                                       Key          Value

    ----         -------                                     -------       -------

    C              1                                              D                3

    A              2

    Thank you.

  • Amed H,

    Format-Wide will put the columns across the screen but can only be used with a single column