{"id":9881,"date":"2006-08-01T03:28:00","date_gmt":"2006-08-01T03:28:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/powershell\/2006\/08\/01\/encoding-operations-knowledge\/"},"modified":"2019-02-18T13:21:28","modified_gmt":"2019-02-18T20:21:28","slug":"encoding-operations-knowledge","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/powershell\/encoding-operations-knowledge\/","title":{"rendered":"Encoding Operations Knowledge"},"content":{"rendered":"<p>One of the primary goals of Windows PowerShell is to encode operations knowledge.&nbsp;&nbsp; Consider the example of finding out what domain role a computer plays.&nbsp; If you look at the WMI class WIN32_COMPUTERSYSTEM,&nbsp;you&#8217;ll see that it tells you this information:<\/p>\n<p><font face=\"Courier New\" size=\"1\">&nbsp; PS&gt; <strong><font color=\"#0000ff\">Get-WMiObject Win32_computerSystem |fl dom*<\/font><\/strong><\/font><br \/><font face=\"Courier New\" size=\"1\">Domain&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: ntdev.corp.microsoft.com<br \/><strong><font color=\"#ff0000\" size=\"2\"><font size=\"1\">DomainRole&nbsp; : 1<\/font><br \/><\/font><\/strong><\/font><\/p>\n<p>So there you have it, my computer plays the &#8220;1&#8221; domainrole.&nbsp; Clear as mud right?&nbsp; So now you sit there and ask youself, &#8220;What the heck is a 1?&#8221;.&nbsp; If you search around the internet&nbsp;you might find:<\/p>\n<p><a href=\"http:\/\/msdn.microsoft.com\/library\/default.asp?url=\/library\/en-us\/wmisdk\/wmi\/win32_computersystem.asp\">http:\/\/msdn.microsoft.com\/library\/default.asp?url=\/library\/en-us\/wmisdk\/wmi\/win32_computersystem.asp<\/a><\/p>\n<p>This has a table which tells you that 1&nbsp;means &#8220;Member Workstation&#8221;.&nbsp; Great &#8211; so now you acquired a bit of knowledge about the system.&nbsp; The question then is, how will you remember this and\/or communicate it.&nbsp; Someone once told me that he could tell whether a picture of an IT Pro&#8217;s workstation was real or not by the number of stickies on their monitor.&nbsp; This is one strategy for encoding this operational knowledge (or folklore) &#8211; put&nbsp; it on a sticky and post it on your monitor.&nbsp; The limitations of this approach should be obvious.<\/p>\n<p>The other thing you could do is to encode it in a script.&nbsp; If you where short-sighted, you would hardcode this information into the particular script you were working on.&nbsp; A better approach would be to have a dedicated script for this function that you could call anytime\/anywhere and share with others:<\/p>\n<p><font face=\"Courier New\" size=\"1\">PS&gt; <strong><font color=\"#0000ff\">cat Get-DomainRole.Ps1<\/font><\/strong><\/font><\/p>\n<p><font face=\"Courier New\" size=\"1\">switch ((Get-WmiObject Win32_ComputerSystem).DomainRole)<br \/>{<br \/>0&nbsp; {&#8220;Standalone Workstation&#8221;}<br \/>1&nbsp; {&#8220;Member Workstation&#8221;}<br \/>2&nbsp; {&#8220;Standalone Server&#8221;}<br \/>3&nbsp; {&#8220;Member Server&#8221;}<br \/>4&nbsp; {&#8220;Backup Domain Controller&#8221;}<br \/>5&nbsp; {&#8220;Primary Domain Controller&#8221;}<br \/>default {&#8220;Unknown&#8221;}<br \/>}<br \/>PS&gt; <strong><font color=\"#0000ff\">.\\Get-DomainRole.Ps1<br \/><\/font><\/strong>Member Workstation<\/font><\/p>\n<p>Now this is encoded in a way that can be shared and called anywhere anytime &#8211; you just need to remember that it exists and know where to find it.&nbsp; Our strong naming guidelines help here but there is another step you can take to make this even easier.&nbsp; You can extend the type with this information.&nbsp; Then whenever you get the object, you always have this information available.&nbsp; <\/p>\n<p>You do this by using our Type Extension system.&nbsp; You can create a file My.Types.ps1xml that contains info like this:<\/p>\n<p><font face=\"Courier New\" size=\"1\">&lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;utf-8&#8243; ?&gt;<br \/>&lt;Types&gt;<br \/>&nbsp;&nbsp;&lt;Type&gt;<br \/>&nbsp;&nbsp;&nbsp; &lt;Name&gt;System.Management.ManagementObject#root\\cimv2\\Win32_ComputerSystem&lt;\/Name&gt;<br \/>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &lt;Members&gt;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ScriptProperty&gt;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Name&gt;DomainRoleStr&lt;\/Name&gt;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;GetScriptBlock&gt;<br \/>switch ($this.DomainRole)<br \/>{<br \/>0&nbsp; {&#8220;Standalone Workstation&#8221;}<br \/>1&nbsp; {&#8220;Member Workstation&#8221;}<br \/>2&nbsp; {&#8220;Standalone Server&#8221;}<br \/>3&nbsp; {&#8220;Member Server&#8221;}<br \/>4&nbsp; {&#8220;Backup Domain Controller&#8221;}<br \/>5&nbsp; {&#8220;Primary Domain Controller&#8221;}<br \/>default {&#8220;Unknown&#8221;}<br \/>}<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/GetScriptBlock&gt;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/ScriptProperty&gt;<br \/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/Members&gt;<br \/>&nbsp;&nbsp;&nbsp; &lt;\/Type&gt;<br \/>&lt;\/Types&gt;<\/font><\/p>\n<p>Then in your profile file have a line like this:<\/p>\n<p><font face=\"Courier New\" color=\"#7fffd4\" size=\"1\"><strong><font color=\"#0000ff\">Update-Typedata &lt;path to this file<\/font>&gt;<\/strong><\/font><\/p>\n<p>This reads the XML file and extends the types that it describes.&nbsp; In this case you&#8217;ve said that you want to extend the WMI type root\\cimv2\\WIN32_ComputerSystem with the property DomainRoleStr whose value is retrieved by running the script provided.&nbsp; Once you do this you can do the following:<\/p>\n<p><font face=\"Courier New\" size=\"1\">&nbsp; PS&gt; <strong><font color=\"#0000ff\">Get-WMiObject Win32_computerSystem |fl dom*<\/font><\/strong><\/font><br \/><font face=\"Courier New\" color=\"#ff0000\" size=\"1\"><strong>DomainRoleStr &nbsp;: Member Workstation<br \/><\/strong><\/font><font face=\"Courier New\" size=\"1\">Domain&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : ntdev.corp.microsoft.com<br \/><strong><font color=\"#ff0000\" size=\"2\"><font color=\"#000000\" size=\"1\">DomainRole&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: 1<br \/><\/font><\/font><\/strong><\/font><font face=\"Courier New\" size=\"1\"><strong><font color=\"#ff0000\" size=\"2\"><font color=\"#000000\" size=\"1\"><\/font><\/font><\/strong><\/font><\/p>\n<p><font face=\"Courier New\" size=\"1\"><font color=\"#ff0000\" size=\"2\"><font color=\"#000000\" size=\"1\"><font face=\"Times New Roman\" size=\"3\">You have now extended the typesystem with your operational knowledge (you have &#8220;formalized your folklore&#8221;).&nbsp; Now you can share this with everyone and they don&#8217;t need to know that there is a script somewhere &#8211; you totally cut out that whole frustration cycle.&nbsp; They won&#8217;t even be able to tell that WMI class doesn&#8217;t provide this information unless they drill into the details: <br \/><\/font><\/font><\/font><\/font><font face=\"Courier New\" size=\"1\"><font color=\"#ff0000\" size=\"2\"><font color=\"#000000\" size=\"1\"><font face=\"Times New Roman\" size=\"3\"><br \/><font face=\"Courier New\"><font size=\"1\">PS&gt; <font color=\"#0000ff\">Get-WMiObject Win32_computerSystem |gm dom*<br \/><\/font><\/font><\/font><br \/><font face=\"Courier New\" size=\"1\">&nbsp;&nbsp; TypeName: System.Management.ManagementObject#root\\cimv2\\Win32_ComputerSy<br \/>stem<\/font><\/p>\n<p><font face=\"Courier New\"><font size=\"1\">Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MemberType&nbsp;&nbsp;&nbsp;&nbsp; Definition<br \/>&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;-&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;-<br \/>Domain&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.String Domain {get;set;}<br \/>DomainRole&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.UInt16 DomainRole {get;set;}<br \/><strong><font color=\"#ff0000\">DomainRoleStr ScriptProperty System.Object DomainRoleStr {get=switch ($t&#8230;<\/font><\/strong><\/font><\/font><\/p>\n<p>&nbsp;<\/p>\n<p>Extending the typesystem is a critical skill to learn because it makes it easy to encode operations knowledge (formalize folklore) and share it with others.&nbsp; By sharing this information &#8211; we can help each other get smarter faster.<\/p>\n<p>Enjoy!<\/p>\n<p>Jeffrey Snover [MSFT]<br \/>Windows PowerShell\/Aspen Architect<br \/>Visit the Windows PowerShell Team blog at:&nbsp;&nbsp;&nbsp; <a href=\"http:\/\/blogs.msdn.com\/PowerShell\">http:\/\/blogs.msdn.com\/PowerShell<\/a><br \/>Visit the Windows PowerShell ScriptCenter at:&nbsp; <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/hubs\/msh.mspx\">http:\/\/www.microsoft.com\/technet\/scriptcenter\/hubs\/msh.mspx<\/a><\/p>\n<p>&nbsp;<\/p>\n<p>PSMDTAG:FAQ: What is the DomainRole of a computer?<\/p>\n<p>PSMDTAG:WMI: Win32_ComputerSystem<\/p>\n<p>PSMDTAG:TypeExtension: Win32_ComputerSystem<\/p>\n<p>PSMDTAG:PHILOSOPHY: Use type extensions to encode operations knowledge.<\/p>\n<p><\/font>&nbsp;<\/p>\n<p><\/font><\/font><\/font><\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of the primary goals of Windows PowerShell is to encode operations knowledge.&nbsp;&nbsp; Consider the example of finding out what domain role a computer plays.&nbsp; If you look at the WMI class WIN32_COMPUTERSYSTEM,&nbsp;you&#8217;ll see that it tells you this information: &nbsp; PS&gt; Get-WMiObject Win32_computerSystem |fl dom*Domain&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: ntdev.corp.microsoft.comDomainRole&nbsp; : 1 So there you have it, my [&hellip;]<\/p>\n","protected":false},"author":600,"featured_media":13641,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[49,10,11,26],"class_list":["post-9881","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-powershell","tag-adapted-type-system","tag-faq","tag-philosophy","tag-wmi"],"acf":[],"blog_post_summary":"<p>One of the primary goals of Windows PowerShell is to encode operations knowledge.&nbsp;&nbsp; Consider the example of finding out what domain role a computer plays.&nbsp; If you look at the WMI class WIN32_COMPUTERSYSTEM,&nbsp;you&#8217;ll see that it tells you this information: &nbsp; PS&gt; Get-WMiObject Win32_computerSystem |fl dom*Domain&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;: ntdev.corp.microsoft.comDomainRole&nbsp; : 1 So there you have it, my [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/9881","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/users\/600"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/comments?post=9881"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/9881\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media\/13641"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media?parent=9881"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/categories?post=9881"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/tags?post=9881"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}