{"id":73621,"date":"2015-09-01T00:01:00","date_gmt":"2015-09-01T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2015\/09\/01\/powershell-5-create-simple-class\/"},"modified":"2019-02-18T09:35:24","modified_gmt":"2019-02-18T16:35:24","slug":"powershell-5-create-simple-class","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/powershell-5-create-simple-class\/","title":{"rendered":"PowerShell 5: Create Simple Class"},"content":{"rendered":"<p><b style=\"font-size:12px\">Summary<\/b><span style=\"font-size:12px\">: Ed Wilson, Microsoft Scripting Guy, talks about creating a simple class in Windows PowerShell 5.0 in Windows 10.<\/span><\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. The good news is that so far the weather person has been wrong&mdash;every single day for the last five days in a row. The bad news is that, well, unfortunately, I believed the weather person, and so I have been huddled in at home, looking out the windows for a storm that never arrived.<\/p>\n<p>We have had a little bit of rain, but not even the normal afternoon thunder storms. Guess I shouldn&rsquo;t complain, but I was hoping to go take pictures of alligators over the weekend.<\/p>\n<p>The other good news is that I have had lots of time to play around with Windows PowerShell&nbsp;5.0 in Windows&nbsp;10 this weekend.<\/p>\n<p><b>&nbsp; &nbsp;Note&nbsp;<\/b> This is the second post in the series about creating classes in Windows PowerShell&nbsp;5.0. You should read <br \/>&nbsp; &nbsp;<a href=\"https:\/\/devblogs.microsoft.com\/scripting\/introduction-to-powershell-5-classes\/\" target=\"_blank\">Introduction to PowerShell 5 Classes<\/a> prior to reading today&rsquo;s post.<\/p>\n<p>So yesterday, I wrote about classes. In general, and I talked about the process of designing a class. I cannot stress this too much:<\/p>\n<p style=\"margin-left:30px\">If you are going to create a class in Windows PowerShell, you must design it.<\/p>\n<p>Nothing is worse than to start writing a module, create a bunch of classes, and then all of a sudden, realize that you need to add (or worse yet, change) one or more properties.<\/p>\n<p>I say worse yet, because I always have the option of inheriting a class and adding properties to it. It may mess up my schema or my design, but I can inherit a class. What messes up things to the point that it requires major rewriting is deciding that a property I implemented as a single string suddenly needs to be an array&#8230;or that something that I implemented as a static property suddenly needs to be dynamically created. It is imperative that I properly design my class at the outset.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/DrScripto_Flipped.jpg\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/DrScripto_Flipped.jpg\" border=\"0\" alt=\" \" \/><\/a><\/p>\n<p><b>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Dr. Scripto says<\/b>: One hour of design work will save 10 hours of rewrite work later.<\/p>\n<h2>Use the Class keyword<\/h2>\n<p>The first thing I need to do is to use the <b>Class<\/b> keyword. This is what creates the class. The syntax is exactly the same as creating a function:<\/p>\n<p style=\"margin-left:30px\">Keyword Name<\/p>\n<p style=\"margin-left:30px\">Opening brace<\/p>\n<p style=\"margin-left:30px\">Closing brace<\/p>\n<p>And there is stuff in the middle. I call these sandwich commands because there is bread on the outside, and the middle is where all the exciting stuff happens.<\/p>\n<p>So, to create the <b>Car<\/b> class, I type:<\/p>\n<p style=\"margin-left:30px\">Class Car<\/p>\n<p style=\"margin-left:30px\">{<\/p>\n<p style=\"margin-left:30px\">}<\/p>\n<p>Then I add my properties. There are several options here. The default terminator is the end-of-line (carriage return line feed), but I can also use a semicolon. Depending on my mood, I prefer the invisible end-of-line terminator, and I place each property command on its own line.<\/p>\n<p><b>&nbsp; &nbsp;Note&nbsp;<\/b> In other things, the Windows PowerShell automatic type system is great, and it works remarkably well. However, <br \/>&nbsp; &nbsp;when creating classes that you really need&mdash;as in, you should (in fact, nearly must) specify the data type for each property. <br \/>&nbsp; &nbsp;If you don&rsquo;t, everything will simply be a System.Object, and will be pretty much useless. If you have a string, an <b>int<\/b>, or a <br \/>&nbsp; &nbsp;<b>DateTime<\/b> object, you must specify that type so that things will work well.<\/p>\n<p>The first property I want to specify is the vehicle identification number (VIN). There probably is an exact pattern for this, and I could use a validation routine for that if it really mattered. For my example, it doesn&rsquo;t matter, and I have no intention on typing more than a few numbers here.<\/p>\n<p>But when I have numbers separated by dashes, those numbers really become strings&mdash;and that is the point. Also, each vehicle has a single VIN, so I do not type an array. It is a single string. Here is my property (it is a System.String):<\/p>\n<p style=\"margin-left:30px\">[String]$vin<\/p>\n<p><b>&nbsp; &nbsp;Note&nbsp;<\/b> The data type goes in square brackets, so that it will cast or constrain the data to be the specified type.<\/p>\n<p>There is a new keyword in Windows PowerShell 5.0 I can use when creating classes: <b>Static<\/b><i>. <\/i>All cars have four wheels (at least for this example), and so, I simply assign that value here. It will be a static property, meaning it is always available. Even if I don&rsquo;t create an instance of the class <b>Car<\/b>, I will be able to figure out that cars have four wheels.<\/p>\n<p>Because the <b>numberOfWheels<\/b> property is the number 4, I cast the property to be an integer by using <b>[int]<\/b>. I could have made it an <b>[int16]<\/b> instead of the default <b>[int32]<\/b> that <b>[int]<\/b> creates, but hey, I am not being that specific.<\/p>\n<p style=\"margin-left:30px\">static [int]$numberOfWheels = 4<\/p>\n<p><b>&nbsp; &nbsp;Note&nbsp;<\/b> What&rsquo;s the difference between <b>[int16]<\/b> and <b>[int32]<\/b>?The short answer is the size of the number that it will hold. <br \/>&nbsp; &nbsp;The specific answer? Check the <b>MaxValue<\/b> static property, as shown here:<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; [int16]::MaxValue<\/p>\n<p style=\"margin-left:30px\">32767<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; [int32]::MaxValue<\/p>\n<p style=\"margin-left:30px\">2147483647<\/p>\n<p>Now, I need to define the <b>numberOfDoors<\/b> property. It could be 2, 4, 5, or more. So I also cast it as an <b>[int]<\/b>. But because the value could be a lot of different things, I do not make it static. This is shown here:<\/p>\n<p style=\"margin-left:30px\">[int]$numberOfDoors<\/p>\n<p>The <b>Year<\/b> property could also be an <b>[int]<\/b>. But I decided to make it a <b>[DateTime]<\/b> object so that I would have access to the properties and methods that a System.DateTime object exposes. I only need to cast the value (constrain) as <b>[datetime]<\/b>, and when I put in my year, Windows PowerShell will convert it to a System.DateTime object. It will fill in other stuff as required. This is shown here:<\/p>\n<p style=\"margin-left:30px\">[datetime]$year<\/p>\n<p>Now I need to add in the <b>Model<\/b> of the car. This is a simple string:<\/p>\n<p style=\"margin-left:30px\">[String]$model<\/p>\n<p style=\"margin-left:30px\">So that is it. Here is the complete class:<\/p>\n<p style=\"margin-left:30px\">Class Car<\/p>\n<p style=\"margin-left:30px\">{<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; [String]$vin<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; static [int]$numberOfWheels = 4<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; [int]$numberOfDoors<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; [datetime]$year<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; [String]$model<\/p>\n<p style=\"margin-left:30px\">}<\/p>\n<h2>Create an instance of the class<\/h2>\n<p>I can use the <b>New-Object<\/b> cmdlet to create an instance of the <b>Car<\/b> class:<\/p>\n<p style=\"margin-left:30px\">$chevy = New-Object car<\/p>\n<p>I can use the <b>Static<\/b> property operator to view my static property:<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $chevy::numberOfWheels<\/p>\n<p style=\"margin-left:30px\">4<\/p>\n<p>The class and the output from the class are shown here in the Windows PowerShell ISE:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-9-1-15-01.jpg\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-9-1-15-01.jpg\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>Now I can simply assign values to the new <b>Car<\/b> object that is stored in my <b>$chevy<\/b> variable:<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $chevy.vin = 12345<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $chevy.numberOfDoors = 2<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $chevy.year = &quot;5\/1\/2015&quot;<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $chevy.model = &quot;Camero&quot;<\/p>\n<p>When I view the contents of the <b>$chevy<\/b> variable, I can see my <b>Car<\/b> object:<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $chevy<\/p>\n<p style=\"margin-left:30px\">vin&nbsp;&nbsp; numberOfDoors &nbsp; &nbsp; year &nbsp; &nbsp; &nbsp; &nbsp;model<\/p>\n<p style=\"margin-left:30px\">&#8212;&nbsp;&nbsp; &#8212;&#8212;&#8212;&#8212;- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#8212;- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#8212;&#8211;<\/p>\n<p style=\"margin-left:30px\">12345 &nbsp; &nbsp;2 5\/1\/2015 12:00:00 AM Camero<\/p>\n<p>That&#039;s how you create a simple class in Windows PowerShell&nbsp;5.0. Windows PowerShell Classes Week will continue tomorrow when I will talk about adding more stuff to the Windows PowerShell class.<\/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><b>Ed Wilson, Microsoft Scripting Guy<\/b><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Ed Wilson, Microsoft Scripting Guy, talks about creating a simple class in Windows PowerShell 5.0 in Windows 10. Microsoft Scripting Guy, Ed Wilson, is here. The good news is that so far the weather person has been wrong&mdash;every single day for the last five days in a row. The bad news is that, well, [&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":[615,609,3,4,608,45],"class_list":["post-73621","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-classes","tag-powershell-5","tag-scripting-guy","tag-scripting-techniques","tag-windows-10","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Ed Wilson, Microsoft Scripting Guy, talks about creating a simple class in Windows PowerShell 5.0 in Windows 10. Microsoft Scripting Guy, Ed Wilson, is here. The good news is that so far the weather person has been wrong&mdash;every single day for the last five days in a row. The bad news is that, well, [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/73621","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=73621"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/73621\/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=73621"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=73621"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=73621"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}