After the first look at PowerShell 2.0, we already know there are tons of commands – or Commandlets as they are called in PowerShell. Each one of them is a more or less powerful feature by itself but usually, you don’t get very far with a single Commandlet:
Get-WmiObject -listAs a result, you will receive a (very long) list of all known WMI Objects. WMI – or Windows Management Instrumentation – is Microsoft’s implementation of an open platform management environment, also referred to as Web-based Enterprise Management (WBEM). For us, WMI Objects are a great source of information about our computer as well as a great training object for PowerShell!
Back to our Get-WmiObject Commandlet: the result is a rather long tabular overview of all available WMI Objects. That is great if we do not know anything about available WMI Objects and allows us to browse, scan and decide on interesting ones… but what if we know that the objects we are (currently) looking for are all having a Name starting with Win32? Can we shorten the list to only those WMI Objects that actually have a matching name?
The answer is yes – and that is where “pipelining” is coming into the game. Try
Get-WmiObject -list | Where-Object { $_.name -like "Win32*" }to see what happens.
In short, “pipelining” is the passing of a result of one Commandlet to another Commandlet for further processing: in our example, the Commandlet Get-WmiObject returns a large list of object and lists them in a tabular way. From the Column Headers, we know one of the properties of those objects is called Name.
The example above now asks the PowerShell Engine to not directly display the result of the Commandlet but to pass it on to a second Commandlet named Where-Object. Here is what you get as a result of Get-Help Where-Object:
The Where-Object cmdlet selects objects from the set of objects that are passed to it. It uses a script block as a filter and evaluates the script block for each object. If the result of the evaluation is True, the object is returned. If the result of the
evaluation is not True, the object is ignored.
And that is exactly the result you are seeing: only objects that have a Name property starting with Win32 are remaining in the list. But one things that disturbs is the long list of Win32_Perf* Objects. What if we are not interested in the Performance Data Objects?
So far, we have used the Select-Object Commandlet to retain all values that match a specific pattern – we are now going to use it to drop all objects we do not like:
Get-WmiObject -list | Where-Object { $_.name -notlike "Win32_Perf*" } | Where-Object { $_.name -like "Win32*" }What happens here is very similar to the first pipeline example:
- Calling Get-WmiObject -list returns all known WMI Objects. The resulting list of objects is then passed to the next Commandlet in the pipeline.
- By using Where-Object with a -notlike parameter in the pattern, we are keeping anything that does not start with Win32_Perf. The result is a list that contains any known WMI Object but the ones starting with Win32_Perf. That reduced list is then passed on to the next Commandlet in the pipeline.
- Using the already known Where-Object with the -like “Win32*” parameter, the remaining list is filtered any only those objects with a name property beginning with Win32 are retained, further truncating the result set.
This little example demonstrates the power of pipelining: a pipeline can be of any complexity, passing its result to the next Commandlet in the pipeline. Of course, the concatenation of Commandlets needs to make sense, in other words: it is your responsibility to ensure that the result of one Commandlet contains anything the next Commandlet can reasonable handle.
Did you notice the list of returned WMI Objects is not alphabetically sorted? Well, guess what – just another Commandlet in the pipeline can do that for you as well:
Get-WmiObject -list | Where-Object { $_.name -notlike "Win32_Perf*" } | Where-Object { $_.name -like "Win32*" } | Sort-Object NameEnough for today – this leaves you with a very nice, alphabetically sorted list of WMI Objects available within PowerShell 2.0 – ready to be exploited in one of the next rounds.