Naming PowerShell custom objects and setting their default display properties

Learnt a couple of things today. Not in depth, but now I am aware of these features and will explore them in depth someday.

I knew how to create custom objects in PowerShell and I have always tried to return output from my functions/ scripts as custom objects. I was also aware that you can set the default display properties so the output is neater.

Say I create a new object like this:

Notice when I output the object all its properties are output. Usually I may not want that. I may want that only the name property is output and the rest are silent, only shown if asked for.

It’s possible to define the default properties you are interested in. This link gives you more details, the tl;dr summary of which is as follows:

  1. All objects contain a member object called PSStandardMembers which defines the default properties of the object.
  2. The PSStandardMembers object a member object called DefaultDisplayPropertySet. This object contains a property called ReferencedPropertyNames which lists the default displayed properties of the object.
  3. Apart from DefaultDisplayPropertySet you have DefaultKeyPropertySet and DefaultDisplayProperty objects too. I am not sure what DefaultDisplayProperty does but DefaultKeyPropertySet is used when sorting and grouping objects.

To set the PSStandardMembers property of an object one does the following:

Notice now only the properties we specified are shown.

As an aside, and purely because I spent some time trying to figure this out, here’s how DefaultKeyPropertySet influences sorting:

(Thanks to this post which made me realize what DefaultKeyPropertySet does).

Back to DefaultDisplayPropertySet – the problem is that it doesn’t work in PowerShell v2. It’s a bug with PowerShell v2 and this Stack Overflow post gives a workaround which involves creating a temporary ps1xml file for the custom objects and defining its default properties.

I haven’t explored ps1xml files much but the gist of the matter is (1) they are what PowerShell uses to format object output and (2) you can create custom ps1xml files for your custom objects. The Stack Overflow post gives a function that takes an object and an array of properties and sets these properties as the default for that object. It’s a neat function and works as expected, but for a catch …

The catch is that since all custom objects have the same name you can’t set different default properties for different objects. Unless you give a name for the custom object, of course, which differentiates each type of custom object from the other. So how do you go about naming custom objects?

First up, how do you get the current name of an object? From my reflection post we know the following works:

To fiddle with the type name you have to use some hidden members of every object. (This was another new thing learnt today. Didn’t know objects had hidden members too). The way to see these is via Get-Member -Force cmdlet. Have a look at the help for the -Force parameter:

From the help file its clear PSTypeNames is what we are interested in.

The members Clear and Add seem to be what we want:

Instead of clearing the existing types, one can Insert the new type to the top of the list too:

Gotta love it when things fall into place and you have a language that makes it easy to do all these things!

My thanks to this and this post for pointing me towards PSTypeNames.