{"id":74209,"date":"2015-02-03T00:01:00","date_gmt":"2015-02-03T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2015\/02\/03\/registry-cmdlets-first-steps-with-cdxml\/"},"modified":"2019-02-18T10:30:48","modified_gmt":"2019-02-18T17:30:48","slug":"registry-cmdlets-first-steps-with-cdxml","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/registry-cmdlets-first-steps-with-cdxml\/","title":{"rendered":"Registry Cmdlets: First Steps with CDXML"},"content":{"rendered":"<p><b style=\"font-size:12px\">Summary<\/b><span style=\"font-size:12px\">: Richard Siddaway shows how to start creating CDXML cmdlets.<\/span>\nHonorary Scripting Guy, Richard Siddaway, here today filling in for my good friend, The Scripting Guy. This is the second post in a series. Yesterday, in <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2015\/02\/02\/registry-cmdlets-manage-the-registry.aspx\" target=\"_blank\">Registry Cmdlets: Working with the Registry<\/a>, I explained that there aren&rsquo;t any cmdlets for working directly with the registry. I showed some examples of using cmdlets that I&rsquo;ve created to access the registry. The cmdlets are created from the WMI registry class, <b>StdRegProv<\/b>, by using CDXML.\nIn this post, I&rsquo;ll show you how to get started with CDXML. Before that, though, I&rsquo;d better explain CDXML&#8230;\nCmdlet definition XML (CDXML) is a way to create a Windows PowerShell module from a WMI class by using the cmdlets-over-objects technology that was introduced in Windows PowerShell&nbsp;3.0. As usual, it&rsquo;s always easier to show you an example:<\/p>\n<p style=\"margin-left:30px\">&lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;utf-8&#8243;?&gt;<\/p>\n<p style=\"margin-left:30px\">&lt;PowerShellMetadata xmlns=&#8221;http:\/\/schemas.microsoft.com\/cmdlets-over-objects\/2009\/11&#8243;&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&lt;Class ClassName=&#8221;ROOTcimv2Win32_BIOS&#8221;&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp; &lt;Version&gt;1.0&lt;\/Version&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp; &lt;DefaultNoun&gt;Bios&lt;\/DefaultNoun&gt;\n&nbsp;<\/p>\n<p style=\"margin-left:30px\">&nbsp; &lt;InstanceCmdlets&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp; &lt;GetCmdletParameters DefaultCmdletParameterSet=&#8221;DefaultSet&#8221; &gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp; &lt;\/GetCmdletParameters&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp; &lt;\/InstanceCmdlets&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&lt;\/Class&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&lt;\/PowerShellMetadata&gt;\nThe first two lines in the previous command are header information, and they have to be present in all CDXML files. You also need to state the WMI class you want to use:<\/p>\n<p style=\"margin-left:30px\">&lt;Class ClassName=&#8221;ROOTcimv2Win32_BIOS&#8221;&gt;\nThe namespace and class have to be supplied. This is equivalent to:<\/p>\n<p style=\"margin-left:30px\">Get-CimInstance -Namespace root\/CIMV2 -ClassName Win32_BIOS\nYou can only use a single WMI class in a CDXML module. If you need to access several WMI classes in your module, create a CDXML file per class, and use a module manifest to perform the load.\nThe version is arbitrary, and is up to you as to how it is changed as you change the module. Here is an example:<\/p>\n<p style=\"margin-left:30px\">&lt;Version&gt;1.0&lt;\/Version&gt;\nWindows PowerShell cmdlets have a noun-verb naming convention. CDXML allows you to set a default noun:<\/p>\n<p style=\"margin-left:30px\">&lt;DefaultNoun&gt;Bios&lt;\/DefaultNoun&gt;\nIf you don&rsquo;t supply a noun for the name of any cmdlet in your module, it will use the default noun.\nThe following four lines define the standard <b>Get<\/b> cmdlet in the module:<\/p>\n<p style=\"margin-left:30px\">&lt;InstanceCmdlets&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp; &lt;GetCmdletParameters DefaultCmdletParameterSet=&#8221;DefaultSet&#8221; &gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp; &lt;\/GetCmdletParameters&gt;<\/p>\n<p style=\"margin-left:30px\">&lt;\/InstanceCmdlets&gt;\nThe remaining XML closes the tags.\nSave the XML with a .cdxml extension. I&rsquo;ve used Bios.cdxml. You treat the CDXML file as a Windows PowerShell module. It&rsquo;s most closely analogous to a .psm1 file. Create a folder on your module path with the same name as your module and save the file in that folder. The module will be automatically loaded in the same way as any other Windows PowerShell module when you start a Windows PowerShell session.\nIf you are working on the module in a series of stages, save it in a working folder that&rsquo;s not on your module path. You can then load the module directly:<\/p>\n<p style=\"margin-left:30px\">Import-Module .bios.cdxml\nIf you are testing and debugging, you may need to load the module back into your Windows PowerShell session. You can ensure that you get the latest version of the module by using the <b>&ndash;Force<\/b> parameter:<\/p>\n<p style=\"margin-left:30px\">Import-Module .bios.cdxml &ndash;Force<\/p>\n<p style=\"margin-left:30px\">&pound;&gt; Get-Module -Name Bios | Format-Table -AutoSize<\/p>\n<p style=\"margin-left:30px\">ModuleType Version Name ExportedCommands<\/p>\n<p style=\"margin-left:30px\">&#8212;&#8212;&#8212;- &#8212;&#8212;- &#8212;- &#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p style=\"margin-left:30px\">Cim&nbsp;&nbsp;&nbsp; 1.0&nbsp; &nbsp;bios Get-Bios\nThe module contains a single cmdlet: <b>Get-Bios<\/b>. The module type shows as CIM. If you use a module manifest, the module type will change to <b>Manifest<\/b>.\nIf you use <b>Get-Command<\/b> on the cmdlet, for example:<\/p>\n<p style=\"margin-left:30px\">&pound;&gt; Get-Command Get-Bios -Syntax<\/p>\n<p style=\"margin-left:30px\">Get-Bios [-CimSession &lt;CimSession[]&gt;] [-ThrottleLimit &lt;int&gt;] [-AsJob] [&lt;CommonParameters&gt;]\n&#8230;you&rsquo;ll see that there are some parameters that you didn&rsquo;t define: <b>&ndash;CimSession<\/b>, <b>&ndash;ThrottleLimit<\/b>, and <b>&ndash;AsJob<\/b>. These are always generated on a CDXML module. You get this functionality for free. You also get the standard common parameters without any effort on your part.\nYou use the cmdlet in the same manner as any other cmdlet:<\/p>\n<p style=\"margin-left:30px\">&pound;&gt; Get-Bios<\/p>\n<p style=\"margin-left:30px\">SMBIOSBIOSVersion : 2.04.0950<\/p>\n<p style=\"margin-left:30px\">Manufacturer&nbsp;&nbsp; : American Megatrends Inc.<\/p>\n<p style=\"margin-left:30px\">Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 2.04.0950<\/p>\n<p style=\"margin-left:30px\">SerialNumber&nbsp;&nbsp; : 036685734653<\/p>\n<p style=\"margin-left:30px\">Version&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;: OEMA &#8211; 1072009\nThis is the same data and format that you&rsquo;d get by using the WMI class directly:<\/p>\n<p style=\"margin-left:30px\">&pound;&gt; Get-CimInstance -ClassName Win32_BIOS<\/p>\n<p style=\"margin-left:30px\">SMBIOSBIOSVersion : 2.04.0950<\/p>\n<p style=\"margin-left:30px\">Manufacturer&nbsp;&nbsp; : American Megatrends Inc.<\/p>\n<p style=\"margin-left:30px\">Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 2.04.0950<\/p>\n<p style=\"margin-left:30px\">SerialNumber&nbsp;&nbsp; : 036685734653<\/p>\n<p style=\"margin-left:30px\">Version&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;: OEMA &#8211; 1072009\nYou can use <b>Get-Help<\/b> on the cmdlet. It will only show the basic syntax. If you want extensive help, you need to create an XML-based external Help file for the module. There is no way to provide inline, comment-based Help like you can for a Windows PowerShell module.\nNow that you&rsquo;ve seen a basic CDXML module, let&rsquo;s start putting together our Registry module. This code is the first step:<\/p>\n<p style=\"margin-left:30px\">&lt;?xml version=&#8221;1.0&#8243; encoding=&#8221;utf-8&#8243;?&gt;<\/p>\n<p style=\"margin-left:30px\">&lt;PowerShellMetadata xmlns=&#8221;http:\/\/schemas.microsoft.com\/cmdlets-over-objects\/2009\/11&#8243;&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&lt;Class ClassName=&#8221;rootcimv2StdRegProv&#8221;&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp; &lt;Version&gt;1.0.0.0&lt;\/Version&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp; &lt;DefaultNoun&gt;Registry&lt;\/DefaultNoun&gt;\n&nbsp;<\/p>\n<p style=\"margin-left:30px\">&nbsp; &lt;StaticCmdlets&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp; &lt;Cmdlet&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; &lt;CmdletMetadata Verb=&#8221;Get&#8221; Noun=&#8221;RegistrySTRING&#8221; ConfirmImpact=&#8221;Low&#8221;\/&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; &lt;Method MethodName=&#8221;GetSTRINGvalue&#8221;&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp; &lt;ReturnValue&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Type PSType=&#8221;System.UInt32&#8243;\/&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;CmdletOutputMetadata&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/CmdletOutputMetadata&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/ReturnValue&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp; &lt;Parameters&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Parameter ParameterName=&#8221;hDefKey&#8221; &gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Type PSType=&#8221;System.UInt32&#8243; \/&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;CmdletParameterMetadata PSName=&#8221;Hive&#8221;&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/CmdletParameterMetadata&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/Parameter&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Parameter ParameterName=&#8221;sSubKeyName&#8221; &gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Type PSType=&#8221;System.String&#8221; \/&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;CmdletParameterMetadata PSName=&#8221;SubKey&#8221;&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/CmdletParameterMetadata&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/Parameter&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Parameter ParameterName=&#8221;sValueName&#8221; &gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Type PSType=&#8221;System.String&#8221; \/&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;CmdletParameterMetadata PSName=&#8221;ValueName&#8221;&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/CmdletParameterMetadata&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/Parameter&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Parameter ParameterName=&#8221;sValue&#8221;&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Type PSType=&#8221;System.String&#8221; \/&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;CmdletOutputMetadata \/&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/Parameter&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/Parameters&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; &lt;\/Method&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp; &lt;\/Cmdlet&gt;&nbsp;&nbsp;<\/p>\n<p style=\"margin-left:30px\">&nbsp; &lt;\/StaticCmdlets&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&lt;\/Class&gt;<\/p>\n<p style=\"margin-left:30px\">&lt;\/PowerShellMetadata&gt;\nThe first few lines define the class and version, as you&rsquo;ve seen previously. I used <b>Registry<\/b> as the default noun. The next line is very important. In our Registry module, it is:<\/p>\n<p style=\"margin-left:30px\">&lt;StaticCmdlets&gt;\nThe corresponding line in the BIOS example was:<\/p>\n<p style=\"margin-left:30px\">&lt;InstanceCmdlets&gt;\nThe difference is that with the BIOS example, you are working with an instance of the object that exists. When you start your computer, the BIOS loads, and that information is available to you. You can&rsquo;t create another instance of the BIOS!\nOther classes where you are dealing with instances include Win32_LogicalDisk, Win32_ComputerSystem, and Win32_OperatingSystem. These are all objects that exist on your system, and therefore, they can have instances.\nThe <b>Registry<\/b> class is a little different. As you saw yesterday, the <b>StdRegProv<\/b> class provides a set of static methods for working with the registry. You don&rsquo;t have instances in this case. The <b>&lt;StaticCmdlets&gt;<\/b> element tells the system that you are dealing with static members of the class rather than instances of CIM objects.\nEventually, the module will create a cmdlet for most methods in the <b>StdRegProv<\/b> class. To get a quick reminder of the methods available, you can use:<\/p>\n<p style=\"margin-left:30px\">Get-CimClass -ClassName StdRegProv | select -ExpandProperty CimClassMethods\nMany registry properties are strings, so I&rsquo;m going to start with the <b>GetStringValue<\/b> method:<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; &lt;CmdletMetadata Verb=&#8221;Get&#8221; Noun=&#8221;RegistrySTRING&#8221; ConfirmImpact=&#8221;Low&#8221;\/&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; &lt;Method MethodName=&#8221;GetSTRINGvalue&#8221;&gt;\nThe cmdlet metadata sets the verb as <b>Get<\/b> and the noun as <b>RegistrySTRING<\/b> (this is capitalized for demonstration purposes, but feel free to revert to normal Windows PowerShell case conventions if you desire). This cmdlet will be called <b>Get-RegistrySTRING<\/b> and it will use the <b>GetSTRINGvalue<\/b> method.\nThe methods in CIM classes return data and a return value. If the return value is zero (0), it worked correctly. Any other value indicates failure. A return value is useful when troubleshooting registry issues, so you should include it in your cmdlet:<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp; &lt;ReturnValue&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Type PSType=&#8221;System.UInt32&#8243;\/&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;CmdletOutputMetadata&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/CmdletOutputMetadata&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/ReturnValue&gt;\nThe type is very important. It must be <b>System.UInt32<\/b>, that is, an unsigned 32-bit integer. CIM works with unsigned integers, which only have positive values:<\/p>\n<p style=\"margin-left:30px\">&pound;&gt; [uint32]::MinValue<\/p>\n<p style=\"margin-left:30px\">0<\/p>\n<p style=\"margin-left:30px\">&pound;&gt; [uint32]::MaxValue<\/p>\n<p style=\"margin-left:30px\">4294967295\nIn contrast, the standard integer can take positive and negative values:<\/p>\n<p style=\"margin-left:30px\">&pound;&gt; [int32]::MinValue<\/p>\n<p style=\"margin-left:30px\">-2147483648<\/p>\n<p style=\"margin-left:30px\">&pound;&gt; [int32]::MaxValue<\/p>\n<p style=\"margin-left:30px\">2147483647\nThe last step in defining the cmdlet is to supply the information that is required to define its parameters. Each parameter is defined in a separate parameter block. The <b>GetStringValue<\/b> method has four arguments&mdash;three input arguments and one output argument.\n<b>Get-CimClass<\/b> and the WMI documentation refer to method parameters rather than arguments. To avoid additional confusion, I&#8217;m using arguments when I am talking about the method and I&#8217;m using parameters when I am talking about the resultant cmdlet.\nThe first input argument, <b>hDefKey<\/b>, defines the hive to be accessed. Remember that this is a number, for instance:<\/p>\n<p style=\"margin-left:30px\">HKEY_LOCAL_MACHINE = 2147483650 (0x80000002)\nIt is supplied as an unsigned integer and the method argument name is overridden, so the cmdlet parameter name is <b>Hive<\/b> rather than <b>hDefKey<\/b>. This isn&rsquo;t necessary, but it makes the cmdlet easier to use. The name of your cmdlet parameter is your choice&mdash;use whatever makes the cmdlet easier to use for you.<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Parameter ParameterName=&#8221;hDefKey&#8221; &gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Type PSType=&#8221;System.UInt32&#8243; \/&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;CmdletParameterMetadata PSName=&#8221;Hive&#8221;&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/CmdletParameterMetadata&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/Parameter&gt;\nThe <b>sSubKeyName<\/b> and <b>sValueName<\/b> arguments for <b>GetStringValue<\/b> define the value you are reading from the registry. Both use <b>&#8220;System.String&#8221;<\/b> as their type, and I&rsquo;ve overridden the argument names so the cmdlet&rsquo;s parameters are <b>SubKey<\/b> and <b>ValueName<\/b> respectively:<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Parameter ParameterName=&#8221;sSubKeyName&#8221; &gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&lt;Type PSType=&#8221;System.String&#8221; \/&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;CmdletParameterMetadata PSName=&#8221;SubKey&#8221;&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/CmdletParameterMetadata&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/Parameter&gt;\n&nbsp;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Parameter ParameterName=&#8221;sValueName&#8221; &gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Type PSType=&#8221;System.String&#8221; \/&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;CmdletParameterMetadata PSName=&#8221;ValueName&#8221;&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/CmdletParameterMetadata&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/Parameter&gt;\nThe final argument for the <b>GetStringValue<\/b> method is <b>sValue<\/b>. This again is a string, but it is the property for the return object that holds the value read from the registry. <b>&lt;CmdletOutputMetadata \/&gt;<\/b> is required to ensure the data is output:<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Parameter ParameterName=&#8221;sValue&#8221;&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Type PSType=&#8221;System.String&#8221; \/&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;CmdletOutputMetadata \/&gt;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/Parameter&gt;\n<strong>&nbsp; &nbsp;Note<\/strong> &nbsp;Renaming output parameters doesn&rsquo;t seem to be possible.\nSave the file with the CDXML definition as registry1.cdxml. You can load it into Windows PowerShell:<\/p>\n<p style=\"margin-left:30px\">&pound;&gt; Get-Command -Module registry1<\/p>\n<p style=\"margin-left:30px\">CommandType&nbsp; &nbsp;Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;ModuleName<\/p>\n<p style=\"margin-left:30px\">&#8212;&#8212;&#8212;&#8211;&nbsp; &nbsp;&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&#8212;&#8212;&#8212;-<\/p>\n<p style=\"margin-left:30px\">Function&nbsp;&nbsp;&nbsp; Get-RegistrySTRING&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;registry1<\/p>\n<p style=\"margin-left:30px\">&pound;&gt; Get-Command Get-RegistrySTRING -Syntax<\/p>\n<p style=\"margin-left:30px\">Get-RegistrySTRING [-Hive &lt;uint32&gt;] [-SubKey &lt;string&gt;] [-ValueName &lt;string&gt;] [-CimSession &lt;CimSession[]&gt;] [-ThrottleLimit &lt;int&gt;] [-AsJob] [-WhatIf] [-Confirm] [&lt;CommonParameters&gt;]\nYou can use the following commands to use it.\nTo define the hive to use (in this case, HKLM):<\/p>\n<p style=\"margin-left:30px\">&nbsp;[uint32]$hklm = 2147483650\nTo define the subkey and value to read:<\/p>\n<p style=\"margin-left:30px\">&nbsp;$subkey = &#8220;SOFTWAREMicrosoftInternet Explorer&#8221;<\/p>\n<p style=\"margin-left:30px\">&nbsp;$value = &#8220;Version&#8221;\nTo use the cmdlet:<\/p>\n<p style=\"margin-left:30px\">Get-RegistrySTRING -Hive $hklm -SubKey $subkey -ValueName $value\nThis gives the following result:<\/p>\n<p style=\"margin-left:30px\">sValue&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;ReturnValue<\/p>\n<p style=\"margin-left:30px\">&#8212;&#8212;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&#8212;&#8212;&#8212;&#8211;<\/p>\n<p style=\"margin-left:30px\">9.11.9600.17498&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;0\nNow you know how to get started creating cmdlets for working with the registry. This series will continue tomorrow when I will show you how to change the code to enable you to use friendly names for the registry hives, make parameters mandatory, and perform validation on the values input to parameters.\nWe invite you to follow The Scripting Guys 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 an email to The Scripting Guys at <a href=\"http:\/\/blogs.technet.commailto: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>. Until then, remember eat your cmdlets every day with a dash of creativity.\n<b>Richard Siddaway, <\/b>Windows PowerShell MVP and Honorary Scripting Guy<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Richard Siddaway shows how to start creating CDXML cmdlets. Honorary Scripting Guy, Richard Siddaway, here today filling in for my good friend, The Scripting Guy. This is the second post in a series. Yesterday, in Registry Cmdlets: Working with the Registry, I explained that there aren&rsquo;t any cmdlets for working directly with the registry. [&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":[385,26,189,45],"class_list":["post-74209","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-cim","tag-registry","tag-richard-siddaway","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Richard Siddaway shows how to start creating CDXML cmdlets. Honorary Scripting Guy, Richard Siddaway, here today filling in for my good friend, The Scripting Guy. This is the second post in a series. Yesterday, in Registry Cmdlets: Working with the Registry, I explained that there aren&rsquo;t any cmdlets for working directly with the registry. [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/74209","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=74209"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/74209\/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=74209"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=74209"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=74209"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}