PowerShell 3.0 Dynamic Type Data

In PowerShell v2.0 it was possible to manipulate .NET and WMI types to provide additional members and format their output. This was done using types.ps1xml files. Creating these files by hand was pretty difficult. It was nice for packaging into modules with objects that had a lot of properties. We used one in the vWorkspace module for example. In PowerShell v3.0 there is a much easier method to quickly extend types directly from the command line. No ps1xml files needed!

Dynamically Adding Members

The Update-TypeData cmdlet was available in the previous version of PowerShell but it’s intention was to reload ps1xml files into the session. This provided the psuedo-dynamic ability to extend types on the fly. In PowerShell v3, the cmdlet has been updated to include a new parameter set for extending types directly on the command line. Much like the Add-Member cmdlet extends an individual instance of an class, the Update-TypeData can be used to extend all instances of that class.

Take for example the String class. It offers a Substring string method that is used to take a portion of the string and return it. In many other languages there are Left and Right methods that do the same thing but count from the left or right of the beginning of the string. If we wanted to add a Right method to all String instances within our PowerShell session, we could do the following.

PS C:\> Update-TypeData -TypeName System.String -MemberName Right -MemberType ScriptMethod -Value { $this.Substring($this.Length - $args[0], $args[0]) }

Once we have run this command, we can then define a string and use the method.

PS C:\> "123456".Right(3)
456

Notice that we have access to the current object through the $this variable. Just like with Add-Member we can make NoteProperties, CodeMethods, ScriptProperties, etc. This is really powerful because it affects every object of that type in the session.

Adjusting Default Output

The Update-TypeData cmdlet can also update default output from the Format-List and Format-Wide cmdlets. For example, we can use the following command to update the output of Get-UICulture to display the Name, DisplayName, and Calendar properties.

PS C:\> Update-TypeData -TypeName Microsoft.PowerShell.VistaCultureInfo -DefaultDisplayPropertySet Name,DisplayName,Calendar

Now when we use the Format-List, without specifying properties in tandem with the Get-UICulture cmdlet, we will have the following output.

PS C:\> Get-UICulture | Format-List

Name : en-US
DisplayName : English (United States)
Calendar : System.Globalization.GregorianCalendar

Adjusting Object Sorting

Not only can the Update-TypeData cmdlet modify how an object is displayed, it can also modify how an object is sorted and grouped by default. To change this aspect of the object, we can use the DefaultKeyPropertySet parameter of Update-TypeData.

By default, the objects returned by Get-Process are sorted alphabetically by process name.

PS C:\> Get-Process | Sort-Object | Select Name

Name
----
acrotray
AdobeARM
armsvc
audiodg
chrome
chrome
chrome
chrome
...

To change this, we can use the following command line.

PS C:\> Update-TypeData -TypeName System.Diagnostics.Process -DefaultKeyPropertySet WorkingSet
PS C:\> Get-Process | Sort-Object | Select Name,WorkingSet

Name     WorkingSet
----     ----------
Idle     24576
ONENOTEM 700416
itype    720896
System   1130496
smss     1171456
sqlservr 1662976
DynTray  3014656
WLIDSVCM 3272704
armsvc   3936256
PnkBstrA 4235264
LSSrvc   4349952
jusched  4366336
csrss    4489216
wininit  4513792
acrotray 4702208

Neato! 

There is actually a lot more you can do with the Update-TypeData cmdlet than what I’ve just shown. In addition to all of this, we can also modify how objects are serialized. This has some pretty heavy implications that I will have to investigate before being able to blog about that. Sounds like some really interesting functionality.

Finding Pre-existing formatting information

With all this fun we are very likely to start to run into conflicts. The Update-TypeData has a Force parameter that allows us to overwrite pre-existing type data if we so desire. We can also look up type data by using the new and shiny Get-TypeData cmdlet. It accepts a type name and will return a whole host of information about the type data for that type.

PS C:\> Get-TypeData System.Diagnostics.Process | FL *
TypeName : System.Diagnostics.Process
Members : {[__NounName,
System.Management.Automation.Runspaces.NotePropertyData], [Name,System.Management.Automation.Runspaces.AliasPropertyData],[Handles,
System.Management.Automation.Runspaces.AliasPropertyData], [VM,System.Management.Automation.Runspaces.AliasPropertyData]...}
TypeConverter :
TypeAdapter :
IsOverride : False
SerializationMethod :
TargetTypeForDeserialization :
SerializationDepth : 0
DefaultDisplayProperty :
InheritPropertySerializationSet : False
StringSerializationSource :
DefaultDisplayPropertySet : System.Management.Automation.Runspaces.PropertySetData
DefaultKeyPropertySet : System.Management.Automation.Runspaces.PropertySetData
PropertySerializationSet :

That’s a quick overview of the new dynamic type data functionality in PowerShell 3.0. Thanks to June Blender for making me take a deeper look at this!

You can leave a response, or trackback from your own site.

3 Responses to “PowerShell 3.0 Dynamic Type Data”

  1. Mike Shepard says:

    This is awesome. I’ve been familiar with PowerShell ETS since 1.0, but I hadn’t seen it mentioned anywhere that they had added this dynamic functionality.

  2. [...] 3.0 Dynamic Type Data August 1, 2012 robertrieglerwien Leave a comment Go to comments http://csharpening.net/?p=1245 Share this:PrintEmailLike this:LikeBe the first to like this. Categories: Developement Tags: [...]

Leave a Reply


7 + = thirteen

Subscribe to RSS Feed Follow me on Twitter!