|
posted on Monday, January 19, 2009 10:12 AM
Welcome to this addition of the PowerShell ABC's where you'll find 26 posts detailing a component of the PowerShell scripting language, one letter at a time. For today's letter is the letter "S", I will discuss PowerShell's extension of existing object with Synthetic Members. A powerful feature in PowerShell is it's ability to extend existing object types and instances. In doing so, it can overlay a common set of interfaces onto an existing source of data. This is different that the traditional method of sub-classing or creating types derived from other types in other object-oriented programming languages where you would extend a type by creating an entirely new type. In PowerShell you can add members to existing types and objects without having to create new types to do so. Synthetic Members These objects that you can add to existing objects are referred to as Synthetic Members since they are not natively part of the existing object. PowerShell makes use of this ability to dynamically add members to objects for adaptation and extension. This allows you to work with two different objects much the same way. In the provider infrastructure, this becomes useful in that it allows you to write scripts that are independent of the type of object that the provider produces. By adding common attributes such as PSIsContainer and PSPath, you'll have a common way to access whether a provider object is a directory and the physical file system path that object represents. Add-Member The Add-Member Cmdlet can be used to add these dynamic members to an object. The syntax for the Add-Member Cmdlet is as follows: Add-Member [-PassThru] [-Force] -InputObject <psobject> [-MemberType] {AliasProperty | CodeProperty | Property | NoteProperty | ScriptProperty | Properties | PropertySet | Method | CodeMethod | ScriptMethod | Methods | ParameterizedProperty | MemberSet | Event | All} [-Name] <string> [[-Value] <Object>] [[-SecondValue] <Object>] [<CommonParameters>]
As you can see from the syntax, the following Member types can be added to any object (taken from Windows PowerShell in Action by Bruce Payette):
|
| Member Type |
| |
Descriptions |
|
| AliasProperty |
|
An alias property provides an alternate name for an existing property. |
|
|
For example, if there is an existing Length property then you might |
|
|
alias this to Count. |
| CodeProperty |
|
A property that maps to a static method on a .NET class. |
| Property |
|
A native property on the object. In other words, a property that exists |
|
|
on the underlying object that is surfaced directly to the user. For |
|
|
example, there might be a native property Length that we choose to |
|
|
also make available through an extended alias member. |
| NoteProperty |
|
A data-only member on the object (equivalent to a .NET field). |
| ScriptProperty |
|
A property whose value is determined by a piece of PowerShell script. |
| Properties |
|
The collection of properties exposed by this object. |
| PropertySet |
|
A named group of properties. |
| Method |
|
A native method on the underlying object. For example, the |
|
|
Sub-String() method on the class System.String shows up as a method. |
| CodeMethod |
|
A method that is mapped to a static method on a >NET class. |
| ScriptMethod |
|
A method implemented in PowerShell script. |
| ParameterizedProperty |
|
A property that takes both arguments and a value to assign. This is |
|
|
typically used for things like indexers and might look like: |
|
|
$collection.item(2,3) = "hello"; |
|
|
This sets the element at 2,3 in the collection to the value "hello". |
|
Adding Your Own Synthetic Members
If you want to add your own personal stamp to an object, you can do so by using the Add-Member Cmdlet to whatever object you wish. The following script function will allow you to make your mark:
function Add-SyntheticMembers() { param([object]$obj = $null); begin { if ( $obj ) { $obj | Add-Member -Type noteProperty -Name "ABCName" -Value "Powershell ABCs"; $obj | Add-Member -Type noteProperty -Name "ABCDesc" -Value "The Best PowerShell Series"; $obj | Add-Member -Type noteProperty -Name "ABCLocation" -Value "http://devcentral.f5.com/weblogs/joe"; } $obj; } process { if ( $_ ) { $_ | Add-Member -Type noteProperty -Name "ABCName" -Value "Powershell ABCs"; $_ | Add-Member -Type noteProperty -Name "ABCDesc" -Value "The Best PowerShell Series"; $_ | Add-Member -Type noteProperty -Name "ABCLocation" -Value "http://devcentral.f5.com/weblogs/joe"; } } }
In the Add-SyntheticMembers function, I added the code to support the input object as either a command line parameter or as passed in through the pipeline.
Here's an example of using this function: PS C:\> $o = Get-ChildItem C:\foo.txt PS C:\> $o | Add-SyntheticMembers PS C:\> $o | Get-Member TypeName: System.IO.FileInfo Name MemberType Definition ---- ---------- ---------- SetAccessControl Method System.Void SetAccessControl(FileSecurity fileSecurity) ToString Method System.String ToString() ABCDesc NoteProperty System.String ABCDesc=The Best PowerShell Series ABCLocation NoteProperty System.String ABCLocation=http://devcentral.f5.com/weblogs/joe ABCName NoteProperty System.String ABCName=Powershell ABCs PSChildName NoteProperty System.String PSChildName=foo.txt PSDrive NoteProperty System.Management.Automation.PSDriveInfo PSDrive=C
|