From the start, Windows PowerShell differs from other command based environments in that it uses objects to pass data through the pipeline. For example, the Get-Process cmdlet retrieves all the processes running on the local computer, and passes them as Process objects through to the next cmdlet in the pipeline.
The following command line output shows what is displayed when Get-Process is invoked. Each row in the following output corresponds to a Process object that was passed through the pipeline.
PS> get-proc
Handles NPM(K) PM(K) WS(K) VS(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- ----------
254 7 7664 12048 66 173.75 1200 QCTRAY
32 2 1372 2628 31 0.04 1860 DLG
271 6 1216 3688 33 0.03 3816 lg
27 2 560 1920 24 0.01 1768 TpScrex
. . .
However, it is important to realize that not all of the properties of the Process object are displayed by Windows PowerShell. In fact, Windows PowerShell allows you to specify what members of an object are displayed at the command line. To see all of the members of an object that a cmdlet passes through the pipeline as well as the object type, the cmdlet output can be piped to the Get-Member cmdlet. Here is a typical output of the Get-Member cmdlet (not all members are shown in this output).
PS> get-proc|get-member
TypeName: System.Diagnostics.Process
Name MemberType Definition
---- ---------- ----------
Handles AliasProperty Handles = Handlecount
Name AliasProperty Name = ProcessName
. . .
Close Method System.Void Close()
CloseMainWindow Method System.Boolean CloseMainWindow()
. . .
NounName NoteProperty System.String __NounName=Process
BasePriority Property System.Int32 BasePriority {get;}
. . .
When passing objects through the pipeline, Windows PowerShell wraps each object in a PSObject object that is typically transparent to the user. This allows Windows PowerShell to have a consistent mechanism for handling different object types. Cmdlet developers can also use the PSObject object to extend the members of objects defined by their own cmdlets. This feature, along with adapted views of object, is part of the extended type system (ETS) provided by Windows PowerShell.
The Extending Type System
Windows PowerShell uses its PSObject object to extend the types of objects in two ways. First, the PSObject object provides a means to show different views of specific object types. This is referred to as showing an adapted view of an object. Second, the PSObject object provide a means to add members to existing object. Second, by wrapping existing objects (referred to as the base object) within the PSObject object, cmdlet and provider developers can add members to the base object. This allows you to manipulate any .NET object within the shell.
For more information about the classes used by the extended type system, see the Windows PowerShell Extended Type System (ETS) topic in the Windows PowerShell Shell SDK.
Viewing an Adapted View of an Object
Adapted views of objects are defined by Windows PowerShell cmdlets. These cmdlets expose a view of an existing object where only a selected set of its members are directly accessible (an adapted view of an object does not change the existing object).
The following illustration shows the relationship between a PSObject object, its base-object, the adapter that defines the adapted view, and any extended members of the base object. Notice that in this example, method M2 and property P2 are blocked by the adapter. These members are not directly accessible through the Members, Methods, and Properties properties of the PSObject object, however they are indirectly accessible through the BaseObject property.
The following are some of the .NET types whose selected members are accessed through adapters.
The following is an example of the adapted view of the ManagementObject object that represents the current computer. The first line obtains the object by invoking the Get-WmiObject cmdlet. The second line invokes the Get-Member cmdlet that displays
PS>$p = get-wmiobject -class win32_computersystem
PS>$p | get-member
TypeName: System.Management.ManagementObject#root\cimv2\Win32_ComputerSystem
Name MemberType Definition
---- ---------- ----------
JoinDomainOrWorkgroup Method System.Management.ManagementBaseObject JoinDomainOrWorkgroup(System.Stri
Rename Method System.Management.ManagementBaseObject Rename(System.String Name, System
SetPowerState Method System.Management.ManagementBaseObject SetPowerState(System.UInt16 Power
UnjoinDomainOrWorkgroup Method System.Management.ManagementBaseObject UnjoinDomainOrWorkgroup(System.St
AdminPasswordStatus Property System.UInt16 AdminPasswordStatus {get;set;}
AutomaticResetBootOption Property System.Boolean AutomaticResetBootOption {get;set;}
AutomaticResetCapability Property System.Boolean AutomaticResetCapability {get;set;}
BootOptionOnLimit Property System.UInt16 BootOptionOnLimit {get;set;}
Delete ScriptMethod System.Object Delete();
GetType ScriptMethod System.Object GetType();
Put ScriptMethod System.Object Put();
Here are two things to notice about this output
-
Not all the members of the base Win32_computerSystem object are displayed by this adapted view. For example, the cmdlet is designed to not display the AutomaticManagedProfile property of the base object.
-
The last three lines display ScriptMethods that have been added by the cmdlet.
To display these properties, Windows PowerShell uses an instance of PSObject created by the cmdlet that keeps a reference to the original object. The original WMI object is accessible through the BaseObject property.
The following example shows how to display the members of the original object.
PS>$p = get-wmiobject -class win32_computersystem
PS>$p | get-member
TypeName: System.Management.Automation.PSMemberSet
Name MemberType Definition
---- ---------- ----------
Addition of Members to Existing Objects
Members can be added to existing objects so that they can be used consistently with other objects within the shell. The following illustration shows the relationship between a PSObject object, its base class, and the extended members added to the base object. Note that, when adding members, if you add an extended member with the same name as a member of the base object, the extended member will take precedence over the base object member.
Windows PowerShell allows the addition of properties and methods to existing objects using a number of ETS classes, as listed in the following table. Members can be added to the objects programmatically, by defining the object using a custom MyProductName.Types.ps1xml file, and through the command line. The members are represented in the types file using the constants defined in the PSMemberTypes enumeration, for example, "CodeMethod". For more information, see Extending Object Types and Formatting.
Class
|
Definition
|
PSAliasProperty | This class defines an alias property to add to an object to reference another property. |
PSCodeMethod | This class defines a code method to add for an object. To be available, this method must be defined in .NET code and correctly compiled for the object. |
PSCodeProperty | This class defines a code property to add for an object. To be available, this property must be defined in .NET code and correctly compiled for the object. |
PSMemberSet | This class defines a set of members to add for an object. |
PSNoteProperty | This class defines a note property (name-value pair) to add for an object. |
PSScriptMethod | This class defines a method implemented in a script to add for an object. |
PSScriptProperty | This class defines a property implemented in a script to add for an object. |
The following .NET code example shows how to add a note property programmatically to an object.
PSObject psObj = new PSObject("some base object");
psObj.Properties.Add(new PSNoteProperty("MyProperty","Value"));
The following example shows to add a note property at the command line.
$a = "some base object"
$a = $a | add-member Note* MyProperty Value
Access to Serialized Objects
Windows PowerShell uses the PSObject class to allow access to serialized objects written to streams. The Windows PowerShell serialization import mechanism uses PSObject to store the object properties. Then the Windows PowerShell runtime can interact with the stored properties using the associated API.
In the next example, serialized output is provided by the Get-Process cmdlet, which generates a .NET Process object. When the object is deserialized (imported from a serialized state), Windows PowerShell can still access most of its properties.
Note: |
---|
Windows PowerShell can access the properties, but not the methods, of a deserialized object. |
PS> $a=get-process ps
PS> $a
Handles PM(K) WS(K) VS(M) Id ProcessName
------- ----- ----- ----- -- -----------
270 18536 25188 127 804 ps
514 55288 56944 175 2356 ps
PS> get-process ps |export-clixml abc.xml
PS> import-clixml abc.xml
Handles PM(K) WS(K) VS(M) Id ProcessName
------- ----- ----- ----- -- -----------
270 18536 25188 127 804 ps
562 55300 56956 175 2356 ps
Support for Customized Objects
Windows PowerShell supports the creation of new objects based on the PSObject class. These objects will reflect in a customized types file, as indicated in Extending Object Types and Formatting.