PowerShell Overview: Format-Table vs. Select-Object

Can you use the Format-Table cmdlet instead of the Select-Object cmdlet?

Depending on what you're doing, yes, you can. In the lab we included an exercise where we had people retrieve user accounts and then display just the values of the DisplayName and Enabled attributes. To do that, we had them pipe the data to the Select-Object cmdlet, like so:

Get-CsAdUser | Select-Object DisplayName, Enabled

That results in output similar to this:

DisplayName Enabled

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

Ken Myer True

Pilar Ackerman False

David Jaffe True

Aneta Olecka True

Based on that. the question we were asked is this: instead of piping data to Select-Object, could we pipe it to Format-Table instead? You know, using a command like this one:

Get-CsAdUser | Format-Table DisplayName, Enabled

Well, let's see:

DisplayName Enabled

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

Ken Myer True

Pilar Ackerman False

David Jaffe True

Aneta Olecka True

Looks like we can, doesn't it?

In fact, by using the Format-Table cmdlet we can not only get the same output as we can by using Select-Object, but we can actually get even better (i.e., more aesthetically-pleasing) output. By default, any time you display two columns of data in Windows PowerShell the software tends to show one column at the far left of the screen and the other column at the far right, leaving a big giant hole in the middle. If you use Select-Object to determine the properties to be displayed onscreen there isn't much you can do about that; Select-Object doesn't offer many formatting options. With Format-Table, however, you can add the AutoSize parameter, which tells PowerShell to make each column just wide enough to display the data in that column. Here's the command:

Get-CsAdUser | Format-Table DisplayName, Enabled -AutoSize

And here's the output:

DisplayName Enabled

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

Ken Myer True

Pilar Ackerman False

David Jaffe True

Aneta Olecka True

A little nicer looking, and a lot easier to read.

By the way, you can also select property values, and display data onscreen, by using the Format-List cmdlet:

Get-CsAdUser | Format-List DisplayName, Enabled

That gives you output similar to this:

DisplayName : Ken Myer

Enabled : True

DisplayName : Pilar Ackerman

Enabled : False

DisplayName : David Jaffe

Enabled : True

DisplayName : Aneta Olecka

Enabled : True

The moral of the story is this: if all you need to do is display data onscreen then, yes, you can use either Format-Table or Format-List instead of Select-Object. (And, as we've seen, using either of these cmdlets might give you nicer-looking output than Select-Object does.)

However (and this is an important however), you can't always use Format-Table (or Format-List) instead of Select-Object. For example, if you need to pipe data to another cmdlet Format-Table won't give you the expected results. Consider this command, which retrieves information about all your Lync Server-enabled user accounts, pulls out just the DisplayName, Enabled, and SipAddress properties, and then writes that information to a comma-separated values file:

Get-CsUser | Select-Object DisplayName, Enabled, SipAddress | Export-Csv –Path C:\Logs\Users.csv

That's going to give us a CSV file with lines that look like this:

#TYPE Selected.Microsoft.Rtc.Management.ADConnect.Schema.OCSADUser

"DisplayName","Enabled","SipAddress"

"Ken Myer",$True,"sip:kenmyer@litwareinc.com"

"Pilar Ackerman",$False,"sip:pilar@litwareinc.com"

Now, let's try the same thing using Format-Table:

Get-CsUser | Format-Table DisplayName, Enabled, SipAddress | Export-Csv –Path C:\Logs\Users.csv

Here's what that CSV file looks like:

#TYPE Microsoft.PowerShell.Commands.Internal.Format.FormatStartData

"ClassId2e4f51ef21dd47e99d3c952918aff9cd","pageHeaderEntry","pageFooterEntry","autosizeInfo","shapeInfo","groupingEntry"

"033ecb2bc07a4d43b5ef94ed5a35d280",,,,"Microsoft.PowerShell.Commands.Internal.Format.TableHeaderInfo",

"9e210fe47d09416682b841769c78b8a3",,,,,

"27c87ef9bbda4f709f6b4002fa4af63c",,,,,

"27c87ef9bbda4f709f6b4002fa4af63c",,,,,

Yeesh; what's that all about? Well, the problem is that the Select-Object cmdlet passes user objects through the pipeline; we can determine that by looking at the TYPE header:

#TYPE Selected.Microsoft.Rtc.Management.ADConnect.Schema.OCSADUser

However, Format-Table doesn't send user objects through the pipeline. Instead, it passes a table object through the pipeline:

#TYPE Microsoft.PowerShell.Commands.Internal.Format.FormatStartData

That's really not what we want.

So, yes, for displaying data onscreen, use Select-Object, Format-Table, or Format-List. For anything else, stick with Select-Object.

Note. Anything else? In real life as well as in Lync Server PowerShell?

Well, maybe not anything. But most things.