Creating Custom Objects in PowerShell with the Original Object

As I often say, PowerShell is all about the objects. Getting your head around this object nature is one of the primary hurdlers for PowerShell newcomers. Cmdlets write objects to the pipeline, but you can also create your own custom objects either from a script or directly in the console.

Lost and Found : Original Object

In Part 1 of this series, I demonstrated how to use Select-Object to create a custom object in Windows PowerShell. One potential downside to that technique is that you lose the original object. Assuming Select-Object is the last part of your expression, you end up with a Selected object type as you see in Figure 1.

Figure 1: A selected object type

Here’s what the actual result looks like:

PowerShell

1

2

3

4

5

ComputernameRequiredCount NameDisplayName

----------------------------------------

SERENITY2spoolerPrint Spooler

Defining a New Object Member Using Add-Member

But what if I wanted to keep the original object type yet still add these properties? The solution is to define a new object member using the Add-Member cmdlet. If you just need to add a single member, you can do it with a one-line command:

You can specify a number of member types with Add-Member (typically you just need NoteProperty). I give it a new name and assign it a value. You must use –Passthru so that the cmdlet writes the object to the pipeline. But where’s the Foo property? It’s there, but you can’t see it because the default format for this type of object only uses Status, Name, and Displayname. But I can still use the property.

If I had piped this to Get-Member I’d also see the property. Things get a bit trickier when you want to add multiple properties or use something from the existing object. Here’s how I normally handle this situation:

The service object is piped to Foreach-Object, which in turns passes each object to Add-Member. The first expression adds a property that shows the number of required objects. Then I define a variable for the computername depending on the value of Machinename. Notice that only on the last Add-Member do I need to use –Passthru.

Again, I won’t see these properties unless I pipe the expression to Get-Member or Select-Object and grab all properties. But there’s nothing preventing me from using it like this:

By creating a new type of object, I can look at service information in ways the author of Get-Service never imagined. I can filter, sort, and format the results based on my new properties. You can see my results below in Figure 2.

Figure 2 : Using Add-Member Results

The other way you’ll see this used is when creating entirely new objects out of thin air.

Custom Objects Cliffhanger

I’ve seen variations on this idea over the years. There’s nothing wrong with this approach and if you are using it, stick with it. I would certainly encourage you to look at full help and examples for Add-Member, as it can be a valuable scripting tool. I’ll admit there are situations where I use this technique. But generally, when I’m writing custom objects to the pipeline, I think there is an even better way. I’ll cover that in the next part of this series.

MEMBER LOGIN:

BECOME A PETRI MEMBER:

About the Contributor

Jeffery Hicks is an IT veteran with over 25 years of experience, much of it spent as an IT infrastructure consultant specializing in Microsoft server technologies with an emphasis in automation and efficiency. He is a multi-year recipient of the Microsoft MVP Award in Windows PowerShell. He works today as an independent author, teacher and consultant. Jeff has written for numerous online sites and print publications and is a frequent speaker at technology conferences and user groups. His latest book is PowerShell Scripting and Toolmaking.