A PowerShell Object Lesson: Part 3

Doctor Scripto

Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to create custom objects.

Microsoft Scripting Guy, Ed Wilson, is here. Tonight is the PowerScripting PodCast. It is always a big deal around the Scripting House, because the Scripting Wife does all their scheduling for the crew and because of our shared interest in the Windows PowerShell community. Tonight will be a brilliant podcast (as they all are).

Note  This is the third part of a three part series that talk about Windows PowerShell objects.

Creating custom object in Windows PowerShell

One of the cool things to do with Windows PowerShell is to create a custom object. In fact, when I create a function, I normally return an object. I consider it a Windows PowerShell best practice that functions should return objects.

So how do I use Windows PowerShell to create objects? Surprisingly, it is easy. Very easy. What may not be so easy, is finding a good example on the Internet. (Of course, if you search for “PowerShell” and “create custom object” on the Hey, Scripting Guy! Blog, you will find over 300 topics).

The Windows PowerShell 1.0 way

It is a bit sad when I see people using Add-Member to create custom objects. This was the way I had to create custom objects in the Windows PowerShell 1.0 days. Now, this is all good in that Add-Member still works for creating objects, but it is a lot of work.

I think people search for “creating a custom object,” and they arrive at old code somewhere. It is also possible that people search for scripts, find an old script, see how the script creates the custom object, and adopt the technique. Like I said, this is fine. It works. Here is an example of using Add-Member to create a custom object:

myhost = $env:COMPUTERNAME

$date = (get-date).ToString()

$object = New-Object psobject

$object = Add-Member -InputObject $object -MemberType `

 ScriptProperty -name host -value {$myhost} -PassThru

$object = Add-Member -InputObject $object -MemberType `

 ScriptProperty -name date -Value {$date} -PassThru 

$object

When I run the script, the output shown in the figure that follows appears in the output pane of the Windows PowerShell ISE.

Image of command output

When I pipe the $object variable to the Get-Member cmdlet, I see the following output:

PS C:\> $object | Get-Member

 

   TypeName: System.Management.Automation.PSCustomObject

 

Name        MemberType     Definition                      

—-        ———-     ———-                      

Equals      Method         bool Equals(System.Object obj)  

GetHashCode Method         int GetHashCode()               

GetType     Method         type GetType()                  

ToString    Method         string ToString()               

date        ScriptProperty System.Object date {get=$date;} 

host        ScriptProperty System.Object host {get=$myhost;}

The Windows PowerShell 2.0 way

In Windows PowerShell 2.0, it became easier to create custom objects. This is because when I use the New-Object cmdlet, I can specify a hash table for the properties. I still use New-Object to create a new PSObject, but I now can specify the properties via the –Property parameter. I then create a hash table that assigns the property names and the property values.

$myhost = $env:COMPUTERNAME

$date = (get-date).ToString()

$object = New-Object psobject -Property @{

    host = $myhost

    date = $date }

$object 

The script is several lines shorter, and it is a whole lot cleaner (no line continuation marks needed, and no –PassThru switches to confuse people). The command and its output are shown in the following image:

Image of command output

The command still creates a custom object. The members of the object are shown here:

PS C:\> $object | Get-Member

 

   TypeName: System.Management.Automation.PSCustomObject

 

Name        MemberType   Definition                             

—-        ———-   ———-                             

Equals      Method       bool Equals(System.Object obj)         

GetHashCode Method       int GetHashCode()                      

GetType     Method       type GetType()                          

ToString    Method       string ToString()                      

date        NoteProperty System.String date=10/28/2013 5:53:03 PM

host        NoteProperty System.String host=EDLT       

The Windows PowerShell 3.0 way

In Windows PowerShell 3.0 (and this continues in Windows PowerShell 4.0), it is even easier to create custom objects. This is because we added a type accelerator, and therefore it is not necessary to use the New-Object command. I use the [PsCustomObject] type accelerator to cast a hash table that contains property names and values into a custom Windows PowerShell object.

This is by far, the cleanest way to create a custom object. The script is a bit shorter, and it is much more readable than the way I had to do things in the Windows PowerShell 2.0 world.

$myhost = $env:COMPUTERNAME

$date = (get-date).ToString()

$object = [pscustomobject]@{

    host = $myhost

    date = $date }

$object 

The command and associated output are shown in the following image:

Image of command output

When I pipe the object to the Get-Member command, I see the following output:

PS C:\> $object | Get-Member

 

   TypeName: System.Management.Automation.PSCustomObject

 

Name        MemberType   Definition                             

—-        ———-   ———-                             

Equals      Method       bool Equals(System.Object obj)         

GetHashCode Method       int GetHashCode()                      

GetType     Method       type GetType()                         

ToString    Method       string ToString()                      

date        NoteProperty System.String date=10/28/2013 6:04:06 PM

host        NoteProperty System.String host=EDLT                

Join me tomorrow when I have a guest blogger who will talk about Windows PowerShell and security.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy 

0 comments

Discussion is closed.

Feedback usabilla icon