Whenever we write a function or a script and choose what properties to display, we are usually greeted with the usual display of every single property that we used instead of what the the PowerShell cmdlets and other module cmdlets such as ActiveDirectory (to name one) show which is usually 4 or less properties as a table (or list in some cases).
Custom Object
What I want it to be
This is due to how the .ps1xml formatting files are written to make sure that there are only a small number of properties that will be displayed to the user.
Fortunately, we can accomplish this same type of output without the need of creating a formatting file and loading it up (a module would be a different story, but for a single function I don’t think it should be necessary).
First thing that we need to do is create a custom object (PowerShell V3 way)
$object = [pscustomobject]@{ FirstName = 'Bob' LastName = 'Smith' City = 'San Diego' State = 'CA' Phone = '555-5555' Gender = 'Male' Occupation = 'System Administrator' DOB = '02/21/1970' }
Nothing new here. Just the usual display of all of the properties when calling $object.
Because this is a custom object, I want to give it a unique typename.
#Give this object a unique typename $object.PSObject.TypeNames.Insert(0,'User.Information')
Next up is to define the default properties which I can to display when calling this object.
#Configure a default display set $defaultDisplaySet = 'FirstName','LastName','Gender','City'
I now need to create the property set that will be used later on the object to define what will be displayed. I also need to ensure that I specify the label as a ‘DefaultPropertyDisplaySet’ in the object creation.
#Create the default property display set $defaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet(‘DefaultDisplayPropertySet’,[string[]]$defaultDisplaySet)
Now we need to create the member info objects needed by Add-Member.
$PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($defaultDisplayPropertySet)
Lastly, we finish up by using Add-Member to add this new member set into the existing custom object.
$object | Add-Member MemberSet PSStandardMembers $PSStandardMembers
Now let’s check out the finished product!
Just like I had in the beginning! If I want to see everything then I can just use Select-Object –Property *.
Applying this more to a real world scenario, this is how I would end up handling multiple iterations with an object being returned each time.
##Set up the default display set and create the member set object for use later on #Configure a default display set $defaultDisplaySet = 'FirstName','LastName','Gender','City' #Create the default property display set $defaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet(‘DefaultDisplayPropertySet’,[string[]]$defaultDisplaySet) $PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($defaultDisplayPropertySet) 1..10 | ForEach { $object = [pscustomobject]@{ FirstName = (Get-Random -InputObject @('Boe','Bob','Joe','Bill')) LastName = (Get-Random -InputObject @('Stevens','Williams','Smith','Prox')) City = 'San Diego' State = 'CA' Phone = '555-5555' Gender = 'Male' Occupation = 'System Administrator' DOB = '02/21/1970' } #Give this object a unique typename $object.PSObject.TypeNames.Insert(0,'User.Information') $object | Add-Member MemberSet PSStandardMembers $PSStandardMembers #Show object that shows only what I specified by default $Object }
What I’ve done is set up most of the default property set up front before I start the actual work and displaying the object in the ForEach statement. This way I am not repeating a process that only has to be done just once.
As you can see, there is not a lot of work involved in doing this and in the end you get a better way of displaying your output without having to mess around with creating or modifying p1xml files!
Hey Boe,
How do you do this with a PowerShell class?
Pingback: Default formatting of an PSObject - How to Code .NET
Pingback: Default Foratting for Custom Object - How to Code .NET
Hi!
Just arrived to your blog, looking exactly for this, and it worked, except for the fact that I’m still getting a list, not a table. Is there a way to make a table the default output?
Great article; great technology.
But: OMG so much code!
Not what I’d call clean & simple.
And: Can you do it simpler with $OBJ=New-Object PSObject -Property @{…}
In 10 tries, with a 1 in 4 chance, there was no “Boe” in the output. Poor Boe 😦
Awesome article btw!
Does this work with PowerShell 2.0?
I’m having trouble.
It should work with Version 2.0. What kind of issues are you seeing?
Great article, I’ve always wondered how to do that!
Great article. Actually there’s an easier way to configure a default display set:
Update-TypeData -TypeName User.Information -DefaultDisplayPropertySet FirstName,LastName,Gender,City
Oh, and you can insert type names with a shorter command 🙂
$object.PSTypeNames.Insert(…)
Nice, Shay! Now that you have mentioned it, I do remember Update-TypeData but didn’t think of using it for that. Always some great info from you. 🙂