Creating a Custom Type Extension

Take almost any object in PowerShell - a process, a service, or what have you. Pipe it to Get-Member. You'll doubtless notice properties and methods, and perhaps even an event or two. Those are the things that object was "born" with; you'll also notice additional members like ScriptProperty, ScriptMethod, AliasProperty, and so on. Those were dynamically added to the object by PowerShell's Extensible Type System, or ETS. Why? What for?

In most cases, those extensions were added to provide better consistency (giving an object a Name property when it didn't natively have one), convenience (the date/time conversion methods of any WMI object), or to make difficult-to-obtain information easier to access (the various ScriptMethods of a Process object are a good example). 

Most type extensions are defined in a file called types.ps1xml, which is located in PowerShell's installation folder. Don't modify it: It's got a Microsoft digital signature, and modifying the file will break that signature and prevent PowerShell from using it. You can, however, create your own.

In "Windows PowerShell v2: TFM (3rd Edition)" I outlined the various extensions you can define, and provide examples. Here's one: I'm adding an "IsPingable" property to the String object. To do so, I defined the extension in a file called Mine.ps1xml. I then loaded it into the shell by running "Update-TypeData -prepend Mine.ps1xml". That places my extension ahead of any Microsoft might have provided; if I'd used -append instead of -prepend, Microsoft's extensions would have had precedence over mine.

 xml version="1.0" encoding="utf-8" ?>
  <code style="color: #006699; font-weight: bold; ">Types>
   <code style="color: #006699; font-weight: bold; ">Type>
     <code style="color: #006699; font-weight: bold; ">Name>System.StringName>
     <code style="color: #006699; font-weight: bold; ">Members>
       <code style="color: #006699; font-weight: bold; ">ScriptProperty>
         <code style="color: #006699; font-weight: bold; ">Name>IsPingableName>
         <code style="color: #006699; font-weight: bold; ">GetScriptBlock>
 $result = test-connection $this -count 1
 if ($result.statuscode -eq 0) { write $true } else { $false }
         GetScriptBlock>
       ScriptProperty>
     Members>
   Type>
 Types>

With this in place, I can pipe any string to Get-Member:

"Hello" | GM 

to see the new ScriptProperty. From there, I can use it: Just run 

"localhost".IsPingable 

to test it. Of course, it'll only work if the string contains a computer name or IP address, but hopefully you get the idea. It even works if the string is in a variable:

$str = 'localhost'
$str.ispingable

This can be a powerful way to add new functionality to existing objects, in such a way that EVERY object of that type will gain your addition. 




My PowerShell home page (http://windowsitpro.com/go/donjonespowershell) offers access to the latest blog articles, along with PowerShell FAQs - why not bookmark it? You can also get the latest on Windows PowerShell in my Twitter feed @concentrateddon (http://twitter.com/concentrateddon). And, if you’d like to download recent conference materials (slide decks, scripts, etc) I’ve delivered, visit http://ConcentratedTech.com. That site also contains details on upcoming classes and conferences.

Discuss this Blog Entry 1

on Jul 6, 2010
It has been accurately pointed out that I coulda just done a "test-connection $this -count 1 -quiet", which would return True or False, without having to put in the whole If construct. I know... but the problem is I wanted something "script-y." In PowerShell, especially v2, it's getting tougher to find very concise examples that CAN'T just be done with a cmdlet or two, and which DO require a script construct. I had (an admittedly) arbitrary goal of doing something script-ish, but short... so there ya go. But it's a good example of how you often don't have to write a "script" in PowerShell - in many cases a better-written cmdlet will suffice. Thanks, @ShayLevy via Twitter...

Please or Register to post comments.

What's PowerShell with a Purpose Blog?

Don Jones demystifies Windows PowerShell.

Blog Archive

Sponsored Introduction Continue on to (or wait seconds) ×