Click to Rate and Give Feedback
Tips
Here is an overview of the new features you can use in the User State Migration Toolkit (USMT) to simplify migration to Windows 7. ...

Read more!

This tip shows you how to hide a share from users. Pretty sneaky stuff! ...

Read more!

With the Microsoft Filter Pack, you can extend the Windows Search service to support more file types, including OneNote and Zip files. ...

Read more!

When things go wrong with notification, operators do not get notified and problems might not be corrected in a timely manner. Learn how you can prevent this with a fail-safe operator. ...

Read more!

Once you’ve thoroughly researched and planned your implementation of Failover clusters, you’re ready to actually create the cluster. The mechanism to create and manage Failover clusters is the Cluster Administrator application, part of the Administrative Tools folder. Here are the 12 easy steps! ...

Read more!

Related Articles

Don Jones continues his look at how you can use Windows PowerShell to automate user provisioning. In this installment, Don details the function that will create a mail-enabled user in Active Directory.

Don Jones

TechNet Magazine April 2009

...

Read more!

Despite its object oriented nature, Windows PowerShell is also able to parse complicated strings. Don Jones demonstrates how you can do this in Windows PowerShell using Select-String.

Don Jones

TechNet Magazine September 2008

...

Read more!

File compression is even more useful when you can automate the process via scripting. Here are some Windows PowerShell scripts you can use to create and expand cab files.

The Microsoft Scripting Guys

TechNet Magazine April 2009

...

Read more!

The Scripting Guys demonstrate a script that times an activity and writes the results to the registry. After subsequent runs, the script retrieves the previous value from the registry and tells you both the current time and the previous time.

The Microsoft Scripting Guys

TechNet Magazine March 2009

...

Read more!

Automating data entry is more important than ever, and today’s automation language is Windows PowerShell. This article uses Windows PowerShell to collect some data about the local computer and write it to an Office Access database.

The Microsoft Scripting Guys

TechNet Magazine May 2009

...

Read more!

Also by this Author

Don Jones demonstrates a Windows PowerShell-based inventory tool and guides you through the process that goes into building such a solution.

Don Jones

TechNet Magazine November 2008

...

Read more!

Don Jones shares his top six common suggestions to improve Windows PowerShell scripts.

Don Jones

TechNet Magazine July 2009

...

Read more!

When designing Windows PowerShell, a lot of thought was put into security. But, as with any software, Windows PowerShell can still be exposed to malicious code. Here are some recommendations for choosing an Execution Policy that will keep your systems more secure.

Don Jones

TechNet Magazine January 2008

...

Read more!

Don Jones concludes his four-part series on automating user provision with Windows PowerShell. In this final edition, Don discusses adding users to domain groups and modifying directory attributes.

Don Jones

TechNet Magazine June 2009

...

Read more!

Learn how you can implement error-handling in Windows PowerShell.

Don Jones

TechNet Magazine January 2009

...

Read more!

Popular Articles

The new Group Policy Preferences feature found in Windows Server 2008 and Windows Vista provides more than 3,000 settings, greatly expanding what administrators can do with Group Policy. Here’s a guide to using Group Policy Preferences to manage your environment.

Derek Melber

TechNet Magazine January 2009

...

Read more!

Discover how to use the Excel.Application automation model for a more powerful way to process data from your servers and take advantage of the analysis and charting tools built into Excel.

The Microsoft Scripting Guys

TechNet Magazine January 2009

...

Read more!

Project Server 2007 delivers significant enhancements, not only to the features and functionality for users but also for administrators. Alan Maddison explores some of the most significant new features and walks you through the installation and configuration of Microsoft Office Project Server 2007.

Alan Maddison

TechNet Magazine January 2009

...

Read more!

The upcoming release of Microsoft Identity Lifecycle Manager “2” offers many new features and enhancements. Explore the new portal experience and find out how you can cut costs with self-service tools, increase security compliance with business process modeling, and reduce development time with simplified development tools.

Aung Oo

TechNet Magazine January 2009

...

Read more!

Security principals underlie so much of Windows security that it is essential for any administrator to have at least a basic understanding of how the various types of Security principals work and how they are used. Here's what you need to know.

Jesper M. Johansson

TechNet Magazine January 2009

...

Read more!

Our Blog

NAP monitors the health of specified computers when they attempt to connect to a network and includes a number of mechanisms to enforce health requirements. In this article, Geek of All Trades Greg Shields gives readers an overview of these enforcement mechanisms and, as an example, takes a closer look at setting ...

Read more!

Use Windows PowerShell to Manage Virtual Machines Here are a few examples of how you can use Windows PowerShell scripts to manage virtual machines running on a Server Core installation. Note that these scripts are presented as samples and may need to be customized to work in your environment.

Create a New ...

Read more!

Disabling an Unused Part of Group Policy Objects One way to disable a policy is to disable an unused part of the GPO. By disabling part of a policy that isn’t used, the application of GPOs and security will be faster.

Administer Windows Server 2008 Server Core from the Command Prompt ...

Read more!

In the August 2008 issue of TechNet Magazine, Paul Randal wrote an article Top Tips for Effective Database Maintenance.  It was geared toward "involuntary  DBAs" (IT pros who inadvertently wind up responsible for a SQL Server instance).  The article had a great response from our readers so Paul has written another ...

Read more!

Microsoft Forefront is designed to deliver an integrated security solution that makes it much easier to deploy and manage security across an organization’s IT infrastructure. In this, our annual security issue, we feature two articles that describe how Forefront Security protects instant messaging and e-mail.

Protect ...

Read more!

Windows PowerShell Filtering and Formatting Data
Don Jones


There’s no question that Windows PowerShell can, without a lot of work on your part, return a great deal of valuable information. For example, consider the simple Get-WMIObject cmdlet, which can be used to return a list of services on the local computer. The default view, which lists the status, name, and startup mode of
the services running, is essentially a command-line view of the Services console. Windows PowerShell™ just makes it much easier to get to.
But there’s a lot more useful information available for services than just what is shown in the default view. Try running this command:
$s = get-wmiobject win32_service
$s[0] | gm
The first line of the command returns a collection of all services (or, more specifically, all instances of the Win32_Service class from Windows® Management Instrumentation, or WMI), storing them in the $s variable. The second line takes the first service in that collection (ordinal number zero, indicated in square brackets) and pipes it to the Get-Mem­ber cmdlet, which I’ve abbreviated using its alias, gm. The resulting output shows all the properties and methods available for that data type. I’ve decided to use the Win32_Service class in WMI, rather than the built-in Get-Service cmdlet in Win­dows PowerShell, because WMI actually exposes more information than the Microsoft® .NET Service­Controller object, including the Start­Name property. That property tells me the name of the user account that the service is running under. You can check the name of a single instance, such as the first one, as follows:
PS C:\> $s[0].StartName
LocalSystem
However, referring to services by their ordinal number within the collection isn’t very useful since the services aren’t in any particular order. (They are usually listed alphabetically, but not always.) From a management perspective, you’ll probably be most interested in a list of all services and the account each is using to log in with. This would be handy for, say, a compliance audit. So let’s back up a second and look at what WMI is providing by default. I’ll use Get-WMIObject’s shorter alias, gwmi (see Figure 1).
PS C:\> gwmi win32_service

ExitCode  : 0
Name      : AcrSch2Svc
ProcessId : 1712
StartMode : Auto
State     : Running
Status    : OK

ExitCode  : 1077
Name      : Adobe LM Service
ProcessId : 0
StartMode : Manual
State     : Stopped
Status    : OK

This is obviously just a sample, but you can see that the output isn’t really great for a management report. What I want to know is the name of the service and the StartName, which is the account the service is running under. I’d also like the report in a more readable format, rather than this somewhat awkward-looking list. That’s where the formidable formatting and data-filtering cmdlets of Windows PowerShell come into play.

Get the Data You Need
I’m going to start by filtering the data from Get-WMIObject so that the properties I’m interested in are being displayed. The best way to do this is to use the Windows PowerShell Select-Object cmdlet or its simple alias, select. Select is designed to accept a collection of objects—such as the collection returned by Get-WMIObject—and display just the desired properties of those objects. This means I can pipe the output of gwmi to select and specify the two properties I’m interested in. Figure 2 shows the results, which include the Name and StartName properties formatted nicely as a table.
Figure 2 Viewing just the Name and StartName properties in a table (Click the image for a larger view)
If I were producing this report for a compliance audit, however, it really contains too much information. Some of the services are disabled, so it most likely wouldn’t matter to anyone reading the output what account the disabled services would theoretically use. Thus, I’d like to filter out all services that have a startup type of Disabled—that’s the StartMode property of the Win32_Service class.
Windows PowerShell performs object filtering using the Where-Object cmdlet or its shorter alias, where. The where cmdlet accepts a collection of input objects and runs each through a scriptblock to determine whether each object is going to be present in the cmdlet’s output based on a set of defined criteria. Each object that meets the criteria produces a True comparison and is included in the output; objects that produce a False value are not included.
So, I determined that I only want objects whose StartMode property equals Disabled. In Windows PowerShell terms, that evaluation looks like this:
$object.StartMode –eq “Disabled”
Of course, $object is just an example. I’m not actually writing a script and so I don’t have a variable named $object. Within the scriptblock used by where, however, I do have the use of a special variable named $_, which represents the object currently being evaluated by the cmdlet. So my where scriptblock might look like this:
$_.StartMode –eq “Disabled”
I can test that easily enough:
PS C:\> gwmi win32_service | where 
{$_.StartMode -eq “Disabled”}

ExitCode  : 1077
Name      : Alerter
ProcessId : 0
StartMode : Disabled
State     : Stopped
Status    : OK
Of course, in this quick test, the output is back to appearing in the default list-style. And, to conserve space, I’ve only included one service here. But you’ll notice that this output is backwards. I’ve included disabled services, as opposed to excluding them. That’s because I’ve got my scriptblock backwards: I need to include all services where the StartMode is not equal to Disabled, as shown by this modification to my example:
PS C:\> gwmi win32_service | where 
{$_.StartMode -ne “Disabled”}

ExitCode  : 0
Name      : AcrSch2Svc
ProcessId : 1712
StartMode : Auto
State     : Running
Status    : OK
That’s better! Now that the output contains only the services I’m really interested in, I can once again pipe the output to select and specify just the properties I want:
gwmi win32_service | where {$_.StartMode -ne “Disabled”} | select name,startname
This business of piping data from one cmdlet to another and to yet another really illustrates the capabilities of Windows PowerShell. I still haven’t written a script, yet I’ve managed to filter through a large data set to get just the output I’m looking for.

The Right Look
You should keep in mind that the output of select is still a bunch of objects. When I retrieve a nicely formatted table using Windows PowerShell, that’s really the PowerShell.exe rendition of those objects. In other words, Windows PowerShell knows that I, as a mere human, can’t see the objects, so it renders the objects as text. In this case, it rendered the objects as a table, with a column for each property, as illustrated in Figure 2.
This might be sufficient for my auditing purposes. But then again, it might not. Everyone has different needs and Windows PowerShell doesn’t presume to know what your specific needs are. Instead, it gives you the tools to format the output in whatever way works best for you. Four built-in cmdlets—Format-List, Format-Custom, Format-Table, and Format-Wide—are designed to accept a collection of objects (such as the collection returned by select) and format those objects in various ways. Format-Table is basically what Windows PowerShell is already using to format the output of my select cmdlet. For a different look, let’s try Format-List:
gwmi win32_service | where {$_.StartMode -ne “Disabled”} | 
select name,startname | format-list
The result looks a bit like this sample:
name      : AcrSch2Svc
startname : LocalSystem

name      : Adobe LM Service
startname : LocalSystem
The Format-Wide cmdlet is designed to produce a multi-column list of, by default, the first property from each object. Take this line, for example:
gwmi win32_service | where {$_.StartMode -ne “Disabled”} |
 select name,startname | format-wide
It produces a list of service names, which isn’t what I want. The output is missing the StartName (see Figure 3), which is an important piece of information I need in my auditing report.
Figure 3 Output displayed using the Format-Wide cmdlet omits key information--the StartName (Click the image for a larger view)
Since I’m only dealing with two properties, it’s likely that either Format-Table or Format-List would be acceptable. But it’s unlikely that an auditor would be happy looking at this information on the screen. She would probably prefer a file of some kind.

Exporting Data
So how might an auditor want to view the data? Outputting the list of services and login names to a CSV (comma-separated values) file might be sufficient since the file can then be easily opened in Microsoft Excel®. To create a CSV file, simply pipe your output to the Windows PowerShell Export-CSV cmdlet:
gwmi win32_service | where {$_.StartMode -ne “Disabled”} | 
select name,startname | export-csv c:\services.csv
Of course, in today’s world, CSV seems a bit outdated. Perhaps your auditors would prefer the data to be displayed as a Web page on an intranet server. To do this, start by converting the output to HTML, using the ConvertTo-HTML cmdlet:
gwmi win32_service | where {$_.StartMode -ne “Disabled”} | 
select name,startname | convertto-html
Raw HTML is hard to view, so you’ll need to write the output to a file:
gwmi win32_service | where {$_.StartMode -ne “Disabled”} | 
select name,startname | convertto-html | out-file c:\services.html
The result, shown in Figure 4, is a well-formatted HTML page that can be posted on any Web server without further modification.
Figure 4 Output displayed as a well-formatted HTML page (Click the image for a larger view)

Just the (Relevant) Facts
Windows PowerShell provides you with quick access to a broad range of management data. However, that data in its raw state isn’t always useful in a business sense.
By filtering the data (using where), choosing the desired object properties (using select), and applying an appropriate formatting option (such as Format-Table or Format-List), you can quickly turn this management data into useful information with very little effort. And then, by exporting the data to a file format that can be easily shared, you can take this information beyond your own desktop and communicate valuable information to other people in your organization.

Don Jones is the Director of Projects and Services for SAPIEN Technologies, and coauthor of Windows PowerShell: TFM (SAPIEN Press). Contact Don through his Web site at www.ScriptingAnswers.com.
© 2008 Microsoft Corporation and CMP Media, LLC. All rights reserved; reproduction in part or in whole without permission is prohibited.
Page view tracker