Extending .NET Objects in PowerShell

One of the great features in PowerShell 2.0 is the ability to extend .NET object types to add additional custom properties and methods.  For instance, the type System.String does not have a property called IsANumber that returns whether or not the string is a number.  Typically, you would have to do a TryParse.  By extending the System.String object, we can add such property.

Here’s how it works:

We will create a custom XML file that will define the .NET object that we would like to extend and how we want to extend it.  Then, we will load that XML into our PowerShell session and the new methods/properties will be available to us. 

Types.ps1xml file, located at $pshome ships with PowerShell 2.0  It is a good place to look at example extensions.  Because this file is digitally signed, we cannot modify it directly, this is why we will create a custom XML file.

Let’s get started.

Open PowerShell by right clicking and choosing “Run as Administrator

RunAsAdmin

This next step (which is actually three commands) will create a new XML file “MyCustomTypes.ps1xml” at the $pshome location,  (typically:  C:\Windows\System32\WindowsPowerShell\v1.0) and open it in Notepad.

$mycustfile = “$pshome\MyCustomTypes.ps1xml”; New-Item –ItemType File –Path $mycustfile; notepad $mycustfile Note:
we are using PowerShell 2.0 but the install location for that is called “1.0”

Next, add the following XML to the notepad window that opened:

<?xml version="1.0" encoding="utf-8" ?>
<Types>
  <Type>
    <Name>System.String</Name>
      <Members>
        <ScriptProperty>
          <Name>IsANumber</Name>
          <GetScriptBlock>
                $out = $null; [System.Double]::TryParse($this, [ref] $out)
          </GetScriptBlock>
      </ScriptProperty>
    </Members>
  </Type>
</Types>

The $this property is the current object of the type you are extending.  In our example it will always be a string, since we are extending the System.String object.

Save and close Notepad

Back in PowerShell type the following command to load the custom types xml file and give it higher precedence than any other loaded file:

Update-TypeData -PrependPath $mycustfile

Now, to test that the new property has been added, we can create a new string variable and check the IsANumber property.

RunTest 

Below are a few of the different types of extensibility that you can perform:

<AliasProperty> – defines a new name for an existing property
<CodeMethod> – references a static method of a .NET class as a method for the object
<CodeProperty> – references a static method of a .NET class as a property for the object
<NoteProperty> – defines a property with a static value
<ScriptMethod> – defines a method whose output is the value of a script
<ScriptProperty> – defines a property whose output is the value of a script

For more information:  
get-help about_types.ps1xml  and  get-help update-typedata