{"id":337,"date":"2006-11-30T07:19:26","date_gmt":"2006-11-30T15:19:26","guid":{"rendered":"http:\/\/testblog.sapien.com\/index.php\/2006\/11\/30\/extending-types\/"},"modified":"2006-11-30T07:19:26","modified_gmt":"2006-11-30T15:19:26","slug":"extending-types","status":"publish","type":"post","link":"https:\/\/dev.sapien.com\/blog\/2006\/11\/30\/extending-types\/","title":{"rendered":"Extending Types"},"content":{"rendered":"<p><P>Ever since I found out about PowerShell&#8217;s extensible type system, I&#8217;ve been in love with it. The ability to add methods and properties to existing .NET types is just too cool. For example, I&#8217;ve added a CanPing() method to the String type. Whenever I have a variable containing an address:<\/P><P><FONT face=\"Courier New,Courier,mono\">[string]$computer = &#8220;Server2&#8221;<\/FONT><\/P><P>I can quickly see if it&#8217;s pingable or not:<\/P><P><FONT face=\"Courier New,Courier,mono\">$computer.CanPing()<\/FONT><\/P><P>Very cool. However, I was confused about two points: First, I was under the impression that all type extensions had to go in the types.ps1xml file that comes with PowerShell. Second, I was a bit confused on when it was appropriate to add a method to a type, and when you should instead be creating a whole new cmdlet (or function, or whatever). PowerShell architect Jeffrey Snover to the rescue! I passed along my two uncertainties and he had great responses.<\/P><P>First &#8211; silly me &#8211; you can actually load any .ps1xml file as a type extension, so you can leave Microsoft&#8217;s default one alone and create your own. Simply run:<\/P><P>Update-TypeData MyExtensions.ps1xml<\/P><P>And poof, your custom types are available. So that&#8217;s very cool &#8211; you can actually organize your custom types into multiple files and share them with your friends and family. Or co-workers. Whatever.<\/P><P>For my second question &#8211; should I use a method in an extended type, or an all-new cmdlet? &#8211; Snover had another great answer. There&#8217;s no hard-and-fast rule, but there are some great guidelines. He suggested that a cmdlet be used whenever you&#8217;re dealing with a collection, or a list of objects; a method is, by it&#8217;s nature, designed to act against only a single object.<\/P><P>So, if I made a Ping-Address cmdlet (<EM>Ping<\/EM> is an officially-allowed verb for cmdlets according to the SDK), that cmdlet coudl accept a collection of addresses to ping, and return a collection of results (perhaps just the objects which were pingable successfully). A CanPing() method, on the other hand, would only work against a single address &#8211; the one contained in the instance of String that the method was working against.<\/P><P>Cmdlets have some other advantages &#8211; they can have help, for example, and they support PowerShell&#8217;s ubiquitous parameters. They can use the -whatif and -confirm parameters if they&#8217;re taking potentially harmful actions. So if you want to include those features, a cmdlet is the best choice. <\/P><P>Part of my second question came from the PowerShell Community Extensions project at <A href=\"http:\/\/www.codeplex.com\/Wiki\/View.aspx?ProjectName=PowerShellCX\">http:\/\/www.codeplex.com\/Wiki\/View.aspx?ProjectName=PowerShellCX<\/A>, which is including a Split-String cmdlet. I had some concerns about that, because it essentially duplicates the functionality in the String type&#8217;s built-in Split() method. I&#8217;m still coming down in favor of the method, not a cmdlet, for this one. First, &#8220;Split&#8221; isn&#8217;t an &#8220;official&#8221; PowerShell cmdlet verb, and while that list of official verbs isn&#8217;t hard-and-fast, I&#8217;m trying to stick with it for any cmdlets I design. Second, I can&#8217;t picture a lot of instances where Split-String would operate against multiple sets &#8211; in other words, where you&#8217;d pass in <EM>multiple<\/EM> delimited strings and get back multiple resulting <EM>arrays<\/EM>. I&#8217;m used to Split() (the method) taking a single delimited string and returning a single array, and that fits that way <EM>I&#8217;d <\/EM>use the functionality most. Because splitting a string isn&#8217;t an especially harmful action, there&#8217;s little reason to support -whatif or -confirm arguments, making another argument for a method rather than a cmdlet.<\/P><P>But that&#8217;s not to ding the folks working on the Community Extensions! They may have entirely other ideas about how string splitting is used and a cmdlet might be the perfect format for the functionality they&#8217;re after. Certainly, it&#8217;s nice just to see someone working on extensions like this for PowerShell!<\/P><P>All in all, it&#8217;s good to have these kinds of tips as PowerShell begins its new life, to help make its usage and future development more consistent for everyone.<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p><P>Ever since I found out about PowerShell&#8217;s extensible type system, I&#8217;ve been in love with it. The ability to add methods and properties to existing .NET types is just too cool. For example, I&#8217;ve added a CanPing() method to the String type. Whenever I have a variable containing an address:<\/P><P><FONT face=\"Courier New,Courier,mono\">[string]$computer = &#8220;Server2&#8221;<\/FONT><\/P><P>I can quickly see if it&#8217;s pingable &#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[2],"tags":[],"class_list":["post-337","post","type-post","status-publish","format-standard","hentry","category-general"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/337","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/comments?post=337"}],"version-history":[{"count":0,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/337\/revisions"}],"wp:attachment":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/media?parent=337"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/categories?post=337"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/tags?post=337"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}