Filtering Objects . . . 70 Castrating Objects . . . 73 Sorting Objects . . . 74 Grouping Objects . . . 74 Calculations . . . 76 Intermediate Steps in the Pipeline . . . 76 Comparing Objects . . . 78 Ramifications . . . 78
This chapter includes advanced Windows PowerShell (WPS) pipelining features such as filtering, sorting, grouping, comparing, and calculating.
The chapter introduces a few commandlets that are commonly used (for example,Where-Object,Sort-Object,Group-Object, and Get-Member).
Analyzing Pipeline Content
One of the greatest challenges in working with WPS is to answer the fol-lowing two questions:
1. Which type do the objects, which are placed in the pipeline by a commandlet, have?
2. Which properties and methods do these objects have?
The commandlets’ help is not always “helpful” here. In Get-Service, you can read the following:
RETURN TYPE
System.ServiceProcess.ServiceController
But in Get-Process, it is not much help; it says only this:
RETURN TYPE Object
The WPS documentation ([MS01] and [MS02]) will not help you at all with the properties and methods of the resulting objects. You will find these only in the MSDN documentation about .NET Framework.
The following two helpful commandlets are introduced, which will help you in everyday work with WPS to learn what you really have in the pipeline:
Get-PipelineInfo Get-Member
Get-PipelineInfo
The commandlet Get-PipelineInfo from the PowerShell Extensions of www.IT-Visions.de, delivers three important pieces of information about the pipeline contents (see Figure 4.1):
■ Number of objects in the pipeline (the objects are numbered)
■ Type of objects in the pipeline (name of .NET class)
■ String representations of objects in the pipeline
The phrase string representation needs to be explained: Each .NET object has a method ToString(), which changes the object into a string, as ToString() is implemented in the “mother of all .NET classes,”
System.Object, and is passed on to all .NET classes and thus to all their instances. Whether ToString()delivers a sensible output depends on the relative class. In the case of System.Diagnostics.Process, the class name and process name are delivered. You can easily get this with gps | foreach { $_.ToString() }(see Figure 4.2). On the other hand, the conversion of class System.ServiceProcess.ServiceController, whose instances are delivered by Get-Service, is not so good, because
the string contains only the class name, so the single instances cannot be diversified (see Figure 4.3).
Analyzing Pipeline Content 61
4.ADVANCEDPIPELINING
Figure 4.1 Get_PipelineInfotells us that there are 11 objects in the data directory, 7 of which are subregistries (class DirectoryInfo) and 4 which are files (class FileInfo).
NOTE The conversion into the class name is the standard behavior, inherited fromSystem.Object, and this standard behavior unfortunately is customary, because the developers of most of the .NET classes at Microsoft did not take the initiative to define a sensible string representation.
ToString()generally is not a serialization of the complete object content, but only mirrors the prime key of the object.
Figure 4.2 Use of ToString() on instances of class System.Diagnostics.Process
Figure 4.3 Use of ToString() on instances of class System.
ServiceProcess.ServiceController
Get-Member
The commandlet Get-Member(aliasgm) is another helpful commandlet: It shows the .NET class name of the objects in the pipeline and the proper-ties and methods of this class. The output of Process | Get-Memberis so long that you need two screenshots for the presentation (see Figures 4.4 and 4.5). Get-Memberis included in the basic WPS 1.0 com-mandlet set.
NOTE If there are different kinds of object types in the pipeline, members of all types are displayed, grouped according to the head section, starting with TypeName.
The output shows that from a WPS point of view, a .NET class has seven kinds of members:
■ Methods
■ Properties
■ Property sets
■ Note properties
■ Script properties
■ Code properties
■ Alias properties
Analyzing Pipeline Content 63
4.ADVANCEDPIPELINING
Figure 4.4 Part 1 of the output of Get-Process | Get-Member
NOTE Concerning the previously mentioned member forms, only Method and Property are actual members of the .NET class. All other kinds of members are extensions, which WPS has added to the .NET object via the previously men-tioned Extended Type System (ETS).
Figure 4.5 Part 2 of the output of Get-Process | Get-Member
Methods are operations that you can call on an object and that will start an action, such as Kill(), which ends the process. Methods, however, may also display data or change data within an object.
WARNING To call a method, you must use parentheses at all times, even if there are no parameters. Without parentheses, you will get only information about the method; you will not call the method itself.
Properties are data elements that contain information about an object or with which information can be transferred to an object (for example, MaxWorkingSet). In the screenshots with the output of Get-Process | Get-Member, it is remarkable that there are two methods for each prop-erty (for example, get_MaxWorkingSet()andset_MaxWorkingSet()).
The cause for this lies within the internals of the .NET Framework: Here properties (not fields) are mapped by a pair of methods—one method to fetch the data (called “get” method or Getter), and another method to set the data (called “set” method or Setter).
This means that for you, as the WPS user, you have two possibilities to call data:
■ By using the property
Get-Process | Where-Object { $_.name -eq "iexplore" } | Foreach-Object { $_.MaxWorkingSet }
■ By using the relevant “get” method
Get-Process | Where-Object { $_.name -eq "iexplore" } | Foreach-Object { $_.get_MaxWorkingSet() }
Likewise, you have the option to use the property as follows:
Get-Process | Where-Object { $_.name -eq "iexplore" } | Foreach-Object { $_.MaxWorkingSet = 1413120 }
Alternatively, you can use the relevant “set” method:
Get-Process | Where-Object { $_.name -eq "iexplore" } | Foreach-Object { $_.set_MaxWorkingSet(1413120) }
TIP The beginner might not be so happy about these options as they inflate the output; the advanced user will like it. In the end, there is a great advantage pro-vided by the listing of getters and setters, besides the syntactical freedom. You can recognize which actions are possible on a property. If the setter is missing, the property cannot be changed (for example, StartTimein the class Process). If the getter is missing, you can set only one property. There is no example for this scenario in the class Process. Furthermore, this scenario is much rarer, but becomes evident with keywords, which cannot be regained because they were not saved in plain text, but only as hash values.
Analyzing Pipeline Content 65
4.ADVANCEDPIPELINING
Property sets are a summary of a number of properties under one umbrella. For example, the property set psRessourcescovers all proper-ties that refer to the resource use of a process. Therefore, you do not have to name the single property. You can write the following instead:
Get-Process | Select-Object psRessources | Format-Table
The developers of WPS thought of many things, but did not cover everything. For instance, for one process the preceding command leads to the failure report “Access is denied”; the pseudo-process “Idle” cannot be asked for TotalProcessorTime(see Figure 4.6).
Figure 4.6 The WPS developers didn’t address the special status of the pseudo-process “Idle.”
Property sets do not exist in .NET Framework; they are a specialty of WPS and are defined in the file types.ps1xmlin the installation directory of WPS (see Figure 4.7).
Figure 4.7 Definition of the property sets for the class System.
Diagnostics.Processin types.ps1ml
Note properties are additional data elements that do not come from the data source, but have been added by the WPS infrastructure. In the class process, it’s __NounName, which gives a shortened name to the class. Other classes have numerous note properties. Note properties do not exist in .NET Framework; they are a specialty of PowerShell.
Ascript property is a calculating property that is not saved within the object itself. This does not mean that the calculation has to be a mathe-matical one; it can also be the access to the properties of a subobject. The following command lists all processes with those products belonging to the relevant processes (see Figure 4.8):
Get-Process | Select-Object name, product
This is good to keep in mind when you are looking in your system at a process that you do not know and that you might take for a virus.
The information about the product cannot be found in the process (Windows does not list this information in the Task Manager either), but in the file, which contains the program code for the process. The .NET Framework offers access to this information via MainModule.
FileversionInfo.ProductName. Microsoft offers a shortcut of the command:
Get-Process | Select-Object name,
➥Mainmodule.FileVersionInfo.ProductName
Analyzing Pipeline Content 67
4.ADVANCEDPIPELINING
Figure 4.8 Listing of the calculating property Product
Microsoft offers this shortcut via the script property. This shortcut is defined in the file types.ps1xmlin the installation directory of WPS (see Figure 4.9).
Script properties do not exist in .NET Framework; they are a specialty of WPS.
A code property equals a script property; the program code, however, is not given as script in WPS language, but as .NET code.
An alias property is a short form for a property. It is not based on a calculation, but on a shortening of the name. For example, WSis short for WorkingSet. The alias properties are also defined in the file types.
ps1xml in the installation directory of WPS. Alias properties are also a WPS specialty.
Figure 4.9 Definition of a script property in types.ps1xml
More Information about Get-Member
You can reduce the output of Get-Memberby limiting it to a certain kind of members. You can accomplish this with the parameter –Membertype (or–m). The following command lists only properties:
Get-Process | Get-Member -Membertype Properties
Furthermore, you can set a name filter:
Get-Process | Get-Member *set*
The preceding command lists only those members of the class Processwhose names contain the word set.
Extended Type System (ETS)
As already pointed out, WPS shows for many .NET objects more members than there are actually defined in the class. In some cases, however, mem-bers are suppressed. This is accomplished through the ETS.
The extension of members via ETS is applied to enable the WPS user to display data directly from some .NET classes, which are meta classes for the actual data (for example, ManagementObject for WMI objects, ManagementClass for WMI classes, DirectoryEntry for entries in directory services, and DataRowfor data rows).
Members are suppressed when they are not usable in WPS or if there are better alternatives via extensions.
In the documentation, you find the following commentary from the WPS development team: “Some .NET object members are inconsistently named, provide an insufficient set of public members, or provide insuffi-cient capability. ETS resolves this issue by introducing the ability to extend the .NET object with additional members.” [MSDN04] Simply put, this means that the WPS team is not really satisfied with the development team’s work with the .NET class library.
Analyzing Pipeline Content 69
4.ADVANCEDPIPELINING
The ETS generally packs each object, which had been placed in the pipeline by a commandlet, into a WPS object, type PSObject. Then, the implementation of the class PSObjectdecides what remains visible for the following commandlets and commands.
This decision is influenced by different instruments:
■ WPS object adapters that have been implemented for certain types, such as ManagementObject,ManagementClass,DirectoryEntry, andDataRow
■ Declarations in the types.ps1xml file
■ Members added in the commandlets
■ Members added through the use of the commandlet Add-Member