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 "https://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 "https://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=https://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

About Joe Pruitt

I'm a Sr. Strategic Architect with the DevCentral team. I specialize in iControl and occasionally am asked to play code-monkey for our website.

I've been with F5 since 1998 when Product Development was less than 10 folks. As the original designer and inventor of iControl, I hope I'm help to folks on the iControl group. I've served as F5's technical representitive for WS-I and OASIS but am now primarily focused on Developer Community and building wicked cool stuff out of F5 products.

My favorite quote is: "Try not! Do, or do not. There is no try!" from the infamous Yoda.

When not working on DevCentral issues or building cool projects with F5 gear, I like to write code, play soccer, ski, strum the guitar, and coach sports teams for my kids.

Related Articles


#devops Errors happen, but your users should never see them. Ever. Every once in a while things happen, like errors. They are as inevitable as winter in Wisconsin, rain in Seattle, and that today someone will post a picture of a cat that shows up on your Facebook news feed. Admit it, you looked, didn't you? The inevitability of 404 errors launched an entire "best practice" of web design to include a fun or amusing error page to present to users. Because looking at a stand...
#SDN The network is naturally stratified because flows are not messages, and vice versa.   Once the initial thrill of SDN abated to a dull roar, the issue of what to do about higher order services (layers 4-7) was raised. Thus far, we've seen some fairly expected responses with notions like service chaining and SDN application service insertion into the controller. What's been missing, however, is a discussion on why SDN needs to address higher order services differently in the first pla...
#devops Deployment patterns enabling continuous delivery help align operations with development - and keep user frustration to a minimum One of the most difficult transitions for operations to make is the need to support releases more frequently. While most organizations will never match the velocity of a Facebook or Netflix, there is still a desire to eliminate the "reduced speed zone" most applications run into when trying to move into production. The reason for the reduced spe...

There are currently no comments yet, be the first to post one.

Only registered users may post comments.