PowerShell: Custom Types, and Formatting

So you’ve graduated to the PowerShell elite, you’ve mastered the pipeline, and one-liners seem well trivial.  What now?  For me, I started working on a module, and along the way I was forced to really learn PowerShell’s Type and Formatting subsystems.  As I see advanced functions start to propagate out into the world I wanted to share some of what I learned (As well as provide myself a useful reference guid!).

Why should you care? Well,  in order for your script/module to truly perform like a first class cmdlet.  You must have a custom type.  Having this custom type will cause several built-in automation gremlins to get confused…. I.e. PowerShell doesn’t know how to handle your new object!  With a combination of type, and format data we’ll teach PowerShell how to handle our object. 

First we need a custom object, I’ll use an example slightly above foo.bar..  First things first we need to construct our object, I won’t get too into this as I’m not qualified to speak on the matter.  All I will offer is this I’ve seen examples using c# interfaces as the object construct.  I prefer using a class as it allows me to define multiple Constructors, which become very useful later on in your code!

So far so good right?  Well, we already need a little tweaking.  Consider what happens next when we instantiate our Server object.. 

Notice how PowerShell just repeated the type name over and over again.  That’s because we haven’t told it what we care about and how to display the information in this situation. I know this is a rare case but it’s one I’ve found all to often!  Fortunately this is handled easily enough. Ultimately we will handle this with a format data file, but first we need to extend our types!  While it is possible to do all this work in the format file, I highly advise against it as it will lead to confusion by your users!

First we’ll create a GetAdmin.Types.ps1xml file and add the following, permanently adding a couple script properties to our objects.

As you can see we added a script property to our Net object that will return the the ip in a string.  Then we used that IP property in the IPAddress script property to create a comma separated list of IP’s.  Then we’ll use that list of IP’s as the default view for the network.  This is done with a simple format data file. A quick note with the format data file: it’s a good idea to format to 80chars wide, as this is the default for most 3rd party consoles.

Now when we run our command we’re displaying useful information right from the start, but we haven’t hampered anything.  Remember the full object is still available underneath.

That’s all for now, Next time type conversion!

~Glenn Sizemore

Leave a Reply