Summary: Learn how to display easily consumed information about system services by using Windows PowerShell.
Hey, Scripting Guy! I am still having trouble working with the Out-GridView cmdlet. I sort of understood what you were talking about yesterday, but when I tried it, all I got was errors. What does it mean when it says that it does not accept the input?
—RS
Hello RS,
Microsoft Scripting Guy, Ed Wilson, is here. Today the Scripting Wife and I are heading back from the Mark Minasi Conference. We do not have a lot of time to tarry because tonight the Charlotte PowerShell Users Group has their meeting. We have a really cool presentation by Brian Hitney. We are going to attempt to do a live meeting so we can share the experience with our fellow Windows PowerShell friends.
RS, one thing to keep in mind when you use the Out-GridView cmdlet is that you need to send it usable information. This means staying away from Format* cmdlets such as Format-Table, Format-List, or Format-Wide. The reason for not using the Format* cmdlets is they change the object; therefore, the Out-GridView cmdlet does not know what to do with the incoming properties.
To provide the appropriate filtering information, the Out-GridView cmdlet reads the incoming property types. If those incoming property types change (which is the case when you pipe through a Format* type of cmdlet), Out-GridView does not know how to display the information. The following example illustrates this mutable property type situation. The results of the Get-Service cmdlet returns a ServiceController object. When the ServiceController object pipes to the Format-Table cmdlet, a series of formatting specific objects return instead.
Get-Service | Format-Table name, status | Get-Member
The command and its associated output appear in the image that follows.
The Out-GridView cmdlet does not know what to do with all the different Format* types of objects. If you need to select specific properties to display in the Out-GridView cmdlet, use the Select-Object cmdlet instead of a Format* type of cmdlet (such as Format-Table). In fact, the use of Format-Table and Select-Object are extremely similar. It is common to use Select-Object prior to sending data to Format-Table—especially if you want to limit the number of objects that are returned by a query. For example, the following command chooses the name and status properties from ServiceController objects, but it only returns the first five services.
PS C:\> Get-Service | sort name -Descending | Select-Object -First 5 -Property name,
status | Format-Table
If you leave the Format-Table cmdlet from the end of the command, you have the following command.
PS C:\> Get-Service | sort name -Descending | Select-Object -First 5 -Property name,
Status
If you run both commands and compare the output, you will see the output is amazingly similar. This is shown here.
In general, you can leave the Format-Table cmdlet out of such commands. This makes it easier for you to further process the information, such as sending the output to the Out-GridView cmdlet. For example, RS, to go back to your original problem, sending the first command (with the Format-Table) cmdlet in the command to the Out-GridView cmdlet produces an error. The error, a FormatException, is shown here.
Dropping the Format-Table cmdlet from the end of the command permits the command to work properly. The revised command is shown here.
PS C:\> Get-Service | sort name -Descending | Select-Object -First 5 -Property name,
status | Out-GridView
PS C:\>
The GridView control that is produced by the previous command is shown here.
One thing to keep in mind, is that the Out-GridView cmdlet accepts the format of the input object when creating the GridView control. This means that because the default view from Get-Service only displays three columns (the name, status, and display name), these are the only properties directly available to the GridView control if you pipe the output without any further manipulation.
The easy way to ensure the availability of all properties involves using the Select-Object cmdlet to pick up the additional properties, as shown here.
Get-Service | Select-Object -Property * | Out-GridView
If you do very much preprocessing prior to sending your data to the Out-GridView cmdlet, you may want to create a custom title for the GridView control. The reason for creating a custom title is that by default, the title is the query that creates the control. But if your query is very involved, complex, or confusing, the title will mimic this aspect of your code. A better way is to create a custom title that more directly answers the question, “Why did I create this control?” This technique is shown here.
PS C:\> Get-Service | Select-Object -Property * | Out-GridView -Title "All Service Properties"
The GridView control that displays all the service properties and has a custom title of All Service Properties is shown here.
Although it is certainly possible to use Criteria to filter out running from stopped services when you have produced the GridView control, if you know you only want running services, filter prior to sending the output to the Out-GridView cmdlet. This will make a cleaner way to deal with your data. This technique is shown here.
PS C:\> Get-Service | where { $_.status -eq 'running'} | select * | Out-GridView -Title 'running services'
The custom GridView control that displays all the properties of running services with the title of running services is shown here.
RS, that is all there is to using the Out-GridView cmdlet to display service information. Join me tomorrow when I will spend a bit more time talking about the Out-GridView cmdlet.
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