PowerShell 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

Synthetic5W40These 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
[-MemberType] {AliasProperty | CodeProperty | Property | NoteProperty |
ScriptProperty | Properties | PropertySet | Method |
CodeMethod | ScriptMethod | Methods |
ParameterizedProperty | MemberSet | Event | All}
[-Name]
[[-Value] ]
[[-SecondValue] ]
[]

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

AliasPropertyAn 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.
CodePropertyA property that maps to a static method on a .NET class.
PropertyA 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.
NotePropertyA data-only member on the object (equivalent to a .NET field).
ScriptPropertyA property whose value is determined by a piece of PowerShell script.
PropertiesThe collection of properties exposed by this object.
PropertySetA named group of properties.
MethodA native method on the underlying object.  For example, the
Sub-String() method on the class System.String shows up as a method.
CodeMethodA method that is mapped to a static method on a >NET class.
ScriptMethodA method implemented in PowerShell script.
ParameterizedPropertyA 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

last modified: January 19, 2009

0 Comment(s):


You must be logged in to post comments.