Just about every PowerShell cmdlet is designed to produce textual output. The cmdlet developer creates a default output format based on the information to be delivered. For example, the output of Get-Process is a horizontal table. However, if you need a different output format, PowerShell has a few choices that are discussed below.
This cmdlet produces a columnar list. Here's a sample using Get-Process:
PS C:\> get-process | format-list Id : 720 Handles : 63 CPU : 0.1301872 Name : ApntEx Id : 584 Handles : 105 CPU : 0.5107344 Name : Apoint Id : 404 Handles : 130 CPU : 0.4706768 Name : avgamsvr Id : 444 Handles : 205 CPU : 2.1130384 Name : avgcc …
Even though we've truncated the output, you get the idea. Instead of the regular horizontal table, each process and its properties is listed in a column. As we've pointed when this cmdlet has been used in other examples, the Format-List doesn't use all the properties that you get with the regular cmdlet output. PowerShell tries to help by presenting the information you are likely to need in this format. If you prefer more control over what information is displayed, you can use the -property cmdlet parameter to specify the properties:
PS C:\> get-process winword |format-list -property ` >> name,workingset,id,path >> Name : WINWORD WorkingSet : 32522240 Id : 564 Path : C:\Program Files\Microsoft Office\OFFICE11\WINWORD.EXE PS C:\>
In this example we've called Get-Process seeking specific information on the WinWord process.
How Did You Know?
You might wonder how we knew what properties can be displayed when we use the -property cmdlet. To review, it is important to get to know the Get-Member cmdlet. This command lists all the available properties for the process object:
get-process | get-memberDifferent cmdlets and objects have different properties, especially in WMI.
Just as there are some cmdlets that use a table format as the default, there are some that use a list format. Of course, sometimes you may prefer a table. The format of this Get-Wmiobject expression produces a list by default:
PS C:\> get-wmiobject -class win32_logicaldisk DeviceID : C: DriveType : 3 ProviderName : FreeSpace : 2815565824 Size : 15726702592 VolumeName : Server2003 DeviceID : D: DriveType : 5 ProviderName : FreeSpace : Size : VolumeName : DeviceID : E: DriveType : 3 ProviderName : FreeSpace : 2891620352 Size : 24280993792 VolumeName : XP
This is not too hard to read. However, here's the same cmdlet except using the Format-Table:
PS C:\> get-wmiobject -class win32_logicaldisk |format-table DeviceID DriveType ProviderName FreeSpace Size VolumeName -------- --------- ------------ --------- ---- ---------- C: 3 2815565824 15726702592 Server2003 D: 5 E: 3 2891620352 24280993792 XP PS C:\>
Since the ProviderName property is blank, we can clean-up this output even more by using -property as we did with Format-List:
PS C:\> get-wmiobject -class win32_logicaldisk |format-table ` >> -property deviceID,freespace,size,volumename,drivetype >> deviceID freespace size volumename drivetype -------- --------- ---- ---------- --------- C: 2815565824 15726702592 Server2003 3 D: 5 E: 2891239424 24280993792 XP 3 PS C:\>
Notice that the property headings are in the same order that we specified in the expression. They also use the same case.
This cmdlet lets you tweak the output by using -autosize, which automatically adjusts the table output based on the date:
PS C:\> get-wmiobject -class win32_logicaldisk |format-table ` >> -property deviceID,freespace,size,volumename,drivetype -autosize >> deviceID freespace size volumename drivetype -------- --------- ---- ---------- --------- C: 2815565824 15726702592 Server2003 3 D: 5 E: 2890489856 24280993792 XP 3 PS C:\>
This is the same command as before, except it includes autosize. Notice how neater the output is. Using -autosize eliminates the need to calculate how long lines will be, add padding or scripting voodoo. Now you can format output to meet your requirements without all the string manipulation when using the traditional Cmd.exe shell or even VBScript.
Some cmdlets, like Get-Service, produce a long list of information that scrolls off the console screen. Wouldn't it be nice to get this information in multiple columns across the console screen? We can accomplish this with the Format-Wide cmdlet:
PS C:\> get-service |format-wide Alerter ALG AppMgmt aspnet_state AudioSrv Avg7Alrt Avg7UpdSvc AVGEMS BAsfIpM BITS Browser CiSvc ClipSrv clr_optimization_v2.0.50727_32 COMSysApp CryptSvc CVPND DcomLaunch Dhcp dmadmin dmserver Dnscache ERSvc Eventlog EventSystem FastUserSwitchingCompatibility GrooveAuditService GrooveInstallerService GrooveRunOnceInstaller helpsvc HidServ HTTPFilter …
If you prefer more than two columns, which is the default, use the - column parameter to specify the number of columns:
PS C:\> get-service |format-wide -column 3 Alerter ALG AppMgmt aspnet_state AudioSrv Avg7Alrt Avg7UpdSvc AVGEMS BAsfIpM BITS Browser CiSvc ClipSrv clr_optimization_v2.0.5... COMSysApp CryptSvc CVPND DcomLaunch Dhcp dmadmin dmserver Dnscache ERSvc Eventlog …
However, don't get carried away. The more columns you specify, the more you'll find the output getting truncated.
The Get-Service cmdlet also let's you specify which single property you would like to display:
PS c:\> get-service |format-wide displayname -column 3 Alerter Application Layer Gatew... Application Man... ASP.NET State Service Windows Audio AVG7 Alert Mana... AVG7 Update Service AVG E-mail Scanner Broadcom ASF IP... Background Intelligent . Computer Browser Indexing Service ClipBook .NET Runtime Optimizati... COM+ System App... Cryptographic Services Cisco Systems, Inc. VPN... DCOM Server Pro... DHCP Client Logical Disk Manager Ad... Logical Disk Ma... DNS Client Error Reporting Service Event Log COM+ Event System Fast User Switching Com... Groove Audit Serv Groove Installer Service GrooveRunOnceInstaller Help and Support …
Unlike Format-Table and Format-List that allow multiple properties, Format-Wide only permits a single property. In this example we've specified the service's display name.
PowerShell provides the ability for you to customize how data is presented. Unfortunately it requires defining a new format in a custom XML file, then using the Update-FormatData cmdlet to register it in PowerShell. Frankly, for most administrators this cmdlet requires more effort than it's worth since it requires a certain degree of knowledge about .NET classes.
With this in mind, PowerShell has one custom format that lists the object class and properties that can be useful. Here's an example using the Get-Process cmdlet:
PS C:\> get-process winword |format-custom class Process { Id = 2308 Handles = 431 CPU = 31.0546544 Name = WINWORD } PS C:\>
Compare this output to the same expression, but each using a different format:
PS C:\> get-process winword|format-table Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName ------- ------ ----- ----- ----- ------ -- ----------- 470 19 37076 60908 207 72.60 2308 WINWORD PS C:\> get-process winword|format-list Id : 2308 Handles : 470 CPU : 72.6044 Name : WINWORD PS C:\> get-process winword|format-wide WINWORD PS C:\>
Of course it's up to you to decide which format meets your needs for a given task.
From the Architect
Jeffrey Snover, the PowerShell architect, has a helpful blog entry titled "Use of Wildcards in PowerShell Formatting" that discusses customizing output. You should be able to find this blog entry at:
http://blogs.msdn.com/powershell/archive/2006/04/29/586775.aspx
All the format cmdlets include a parameter called -GroupBy that. allows you to group output based on a specified property. For example, here is a Get-Service expression that groups services by their status such as Running or Stopped. The output below has been edited for brevity.
PS C:\> get-service |format-table -groupby status Status: Stopped Status Name DisplayName ------ ---- ----------- Stopped Alerter Alerter Stopped ALG Application Layer Gateway Service Stopped AppMgmt Application Management Stopped aspnet_state ASP.NET State Service Status: Running Status Name DisplayName ------ ---- ----------- Running AudioSrv Windows Audio Running Avg7Alrt AVG7 Alert Manager Server Running Avg7UpdSvc AVG7 Update Service Running AVGEMS AVG E-mail Scanner Status: Stopped Status Name DisplayName ------ ---- ----------- Stopped BAsfIpM Broadcom ASF IP monitoring service ... Stopped BITS Background Intelligent Transfer Ser... Stopped Browser Computer Browser Stopped CiSvc Indexing Service Stopped ClipSrv ClipBook Stopped clr_optimizatio... .NET Runtime Optimization Service v... Stopped COMSysApp COM+ System Application Status: Running Status Name DisplayName ------ ---- ----------- Running CryptSvc Cryptographic Services Status: Running Status Name DisplayName ------ ---- ----------- Running wuauserv Automatic Updates Running WZCSVC Wireless Zero Configuration Status: Stopped Status Name DisplayName ------ ---- ----------- Stopped xmlprov Network Provisioning Service PS C:\>
As you can see, grouping helps a little bit. However, this is probably not what you expected since the cmdlet appears to be first grouping services alphabetically and then grouping them by status.