{"id":2608,"date":"2013-11-07T00:01:00","date_gmt":"2013-11-07T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2013\/11\/07\/a-powershell-object-lesson-part-3\/"},"modified":"2013-11-07T00:01:00","modified_gmt":"2013-11-07T00:01:00","slug":"a-powershell-object-lesson-part-3","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/a-powershell-object-lesson-part-3\/","title":{"rendered":"A PowerShell Object Lesson: Part 3"},"content":{"rendered":"<p><strong>Summary<\/strong>: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to create custom objects.<\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. Tonight is the <a href=\"http:\/\/powerscripting.wordpress.com\/\" target=\"_blank\">PowerScripting PodCast<\/a>. 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).<\/p>\n<p><strong>Note&nbsp;&nbsp;<\/strong>This is the third part of a three part series that talk about Windows PowerShell objects.<\/p>\n<ul>\n<li>In <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2013\/11\/05\/a-powershell-object-lesson-part-one.aspx\" target=\"_blank\">A PowerShell Object Lesson: Part 1<\/a>, I talked about the advantage of using Windows PowerShell objects, and how they are helpful to the scripter.<\/li>\n<li>In <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2013\/11\/06\/a-powershell-object-lesson-part-2.aspx\" target=\"_blank\">A PowerShell Object Lesson: Part 2<\/a>, I talked about pipelining objects.<\/li>\n<\/ul>\n<h2>Creating custom object in Windows PowerShell<\/h2>\n<p>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.<\/p>\n<p>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 &ldquo;PowerShell&rdquo; and &ldquo;create custom object&rdquo; on the Hey, Scripting Guy! Blog, you will find over <a href=\"http:\/\/social.technet.microsoft.com\/Search\/en-US?query=create%20custom%20object&amp;beta=0&amp;rn=Hey%2c+Scripting+Guy!+Blog&amp;rq=site:blogs.technet.com\/b\/heyscriptingguy\/&amp;ac=5\" target=\"_blank\">300 topics<\/a>).<\/p>\n<h3>The Windows PowerShell 1.0 way<\/h3>\n<p>It is a bit sad when I see people using <strong>Add-Member<\/strong> to create custom objects. This was the way I had to create custom objects in the Windows PowerShell&nbsp;1.0 days. Now, this is all good in that <strong>Add-Member<\/strong> still works for creating objects, but it is a lot of work.<\/p>\n<p>I think people search for &ldquo;creating a custom object,&rdquo; 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 <strong>Add-Member<\/strong> to create a custom object:<\/p>\n<p style=\"padding-left: 30px\">myhost = $env:COMPUTERNAME<\/p>\n<p style=\"padding-left: 30px\">$date = (get-date).ToString()<\/p>\n<p style=\"padding-left: 30px\">$object = New-Object psobject<\/p>\n<p style=\"padding-left: 30px\">$object = Add-Member -InputObject $object -MemberType `<\/p>\n<p style=\"padding-left: 30px\">&nbsp;ScriptProperty -name host -value {$myhost} -PassThru<\/p>\n<p style=\"padding-left: 30px\">$object = Add-Member -InputObject $object -MemberType `<\/p>\n<p style=\"padding-left: 30px\">&nbsp;ScriptProperty -name date -Value {$date} -PassThru&nbsp;<\/p>\n<p style=\"padding-left: 30px\">$object<\/p>\n<p>When I run the script, the output shown in the figure that follows appears in the output pane of the Windows PowerShell ISE.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6283.HSG-11-7-13-01.png\"><img decoding=\"async\" title=\"Image of command output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6283.HSG-11-7-13-01.png\" alt=\"Image of command output\" \/><\/a><\/p>\n<p>When I pipe the <strong>$object<\/strong> variable to the <strong>Get-Member<\/strong> cmdlet, I see the following output:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; $object | Get-Member<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; TypeName: System.Management.Automation.PSCustomObject<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MemberType&nbsp;&nbsp;&nbsp;&nbsp; Definition&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;-&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Equals&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bool Equals(System.Object obj)&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">GetHashCode Method&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int GetHashCode()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">GetType&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type GetType()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">ToString&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string ToString()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ScriptProperty System.Object date {get=$date;}&nbsp;<\/p>\n<p style=\"padding-left: 30px\">host&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ScriptProperty System.Object host {get=$myhost;}<\/p>\n<h3>The Windows PowerShell 2.0 way<\/h3>\n<p>In Windows PowerShell 2.0, it became easier to create custom objects. This is because when I use the <strong>New-Object<\/strong> cmdlet, I can specify a hash table for the properties. I still use <strong>New-Object<\/strong> to create a new PSObject, but I now can specify the properties via the <strong>&ndash;Property<\/strong> parameter. I then create a hash table that assigns the property names and the property values.<\/p>\n<p style=\"padding-left: 30px\">$myhost = $env:COMPUTERNAME<\/p>\n<p style=\"padding-left: 30px\">$date = (get-date).ToString()<\/p>\n<p style=\"padding-left: 30px\">$object = New-Object psobject -Property @{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; host = $myhost<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; date = $date }<\/p>\n<p style=\"padding-left: 30px\">$object&nbsp;<\/p>\n<p>The script is several lines shorter, and it is a whole lot cleaner (no line continuation marks needed, and no<strong> &ndash;PassThru <\/strong>switches to confuse people). The command and its output are shown in the following image:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/4657.HSG-11-7-13-02.png\"><img decoding=\"async\" title=\"Image of command output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/4657.HSG-11-7-13-02.png\" alt=\"Image of command output\" \/><\/a><\/p>\n<p>The command still creates a custom object. The members of the object are shown here:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; $object | Get-Member<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; TypeName: System.Management.Automation.PSCustomObject<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MemberType&nbsp;&nbsp; Definition&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;-&nbsp;&nbsp; &#8212;&#8212;&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Equals&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bool Equals(System.Object obj)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">GetHashCode Method&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int GetHashCode()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">GetType&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type GetType()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">ToString&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string ToString()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NoteProperty System.String date=10\/28\/2013 5:53:03 PM<\/p>\n<p style=\"padding-left: 30px\">host&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NoteProperty System.String host=EDLT &nbsp; &nbsp; &nbsp;&nbsp;<\/p>\n<h3>The Windows PowerShell 3.0 way<\/h3>\n<p>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 <strong>New-Object<\/strong> command. I use the <strong>[PsCustomObject]<\/strong> type accelerator to cast a hash table that contains property names and values into a custom Windows PowerShell object.<\/p>\n<p>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.<\/p>\n<p style=\"padding-left: 30px\">$myhost = $env:COMPUTERNAME<\/p>\n<p style=\"padding-left: 30px\">$date = (get-date).ToString()<\/p>\n<p style=\"padding-left: 30px\">$object = [pscustomobject]@{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; host = $myhost<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; date = $date }<\/p>\n<p style=\"padding-left: 30px\">$object&nbsp;<\/p>\n<p>The command and associated output are shown in the following image:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5556.HSG-11-7-13-03.png\"><img decoding=\"async\" title=\"Image of command output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5556.HSG-11-7-13-03.png\" alt=\"Image of command output\" \/><\/a><\/p>\n<p>When I pipe the object to the <strong>Get-Member<\/strong> command, I see the following output:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; $object | Get-Member<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; TypeName: System.Management.Automation.PSCustomObject<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MemberType&nbsp;&nbsp; Definition&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;-&nbsp;&nbsp; &#8212;&#8212;&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Equals&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bool Equals(System.Object obj)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">GetHashCode Method&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int GetHashCode()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">GetType&nbsp;&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type GetType()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">ToString&nbsp;&nbsp;&nbsp; Method&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string ToString()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NoteProperty System.String date=10\/28\/2013 6:04:06 PM<\/p>\n<p style=\"padding-left: 30px\">host&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NoteProperty System.String host=EDLT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<\/p>\n<p>Join me tomorrow when I have a guest blogger who will talk about Windows PowerShell and security.<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><strong>Ed Wilson, Microsoft Scripting Guy<\/strong>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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 [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[51,3,4,45],"class_list":["post-2608","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-getting-started","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>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 [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/2608","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=2608"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/2608\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=2608"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=2608"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=2608"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}