Interacting with System Registry using WMI
The utility of WMI classes is huge and there are a lot of WMI classes to interact with. Which is of course an awesome thing, but since there are lot of WMI classes sometimes the challenge is figuring out which class you will need for your specific requirement.
Today, lets discuss a WMI class which you will need for interacting with the registry - and the class is StdRegProv.
A little bit of details on the StdRegProv class before we start:
StdRegProv has been a part of Root\Default WMI namespace. However, starting from Windows Vista it is also a part of Root\CIMV2 namespace. Therefore, one can create an instance of StdRegProv class from Root\CIMV2 or Root\Default Namespace. Consider using the Root\Default namespace, if you want your script to be compatible with older versions of Windows Operating System as well.
There is one more thing I want to focus your attention to about this class. You will need following specific numeric values to interact with specific registry hives. Below are the hives and their corresponding numeric values:
Name Value
HKEY_CLASSES_ROOT 2147483648
HKEY_CURRENT_USER 2147483649
HKEY_LOCAL_MACHINE 2147483650
HKEY_USERS 2147483651
HKEY_CURRENT_CONFIG 2147483653
Not to digress, but while writing these values I just realized that this one makes for an excellent example of use of HashTable, doesn't it! Just create a HashTable with the keys as the hive names and assign the corresponding number as the value of each key. Below is an example of what I am talking about:
Now, it indeed becomes easy to access the numeric value of any hive (e.g. $regkey["HKEY_CLASSES_ROOT"] )
Having understood the important pieces of the StdRegProv class, now lets proceed with looking at some useful methods of this class. For this post, I am using the class from Root\Default namespace. Following are the two ways in which we can create a reference to this WMI class:
If you have any doubts on the above 2 methods of referencing a WMI class please refer to my "Introduction to WMI" (https://blogs.msdn.com/b/vishinde/archive/2012/09/15/introduction-to-wmi.aspx) blog post.
The advantage of using Get-WMIObject over [WMIClass] type accelerator is that Get-WMIObject has a -ComputerName parameter. That means you can fetch registry information from a remote machine very easily using the Get-WMIObject cmdlet. That is:
Using a Get-Member on the $regClass will list all the static members of the class:
Formatting this output in a tabular format and wrapping the contents will list all the parameters which are expected by this method as well ( $regClass | Get-Member | Format-Table -Wrap ).
We can use any of the Get.. methods in order to get a value from the registry. Lets say we want to retrieve a String value from the registry, in that case we will use the GetStringValue method. In the example below, we are reading the value of ExecutionPolicy key in the Software\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell folder. As a reminder, $regkey is a HashTable we created earlier and HKEY_LOCAL_MACHINE is one of the keys of the HashTable.
In the output, ReturnValue 0 tells us that the operation was successful and sValue is the actual value. If you want to read just the ouptut, you can Select sValue from the output as shown in the example above.
Just like you can read different types of values using this class, you can read the keys and the values as well using this class. Example:
sNames is an array returned by EnumKey, hence we chose to use the ExpandProperty parameter on sNames to display all the Keys on a particular path. (Not sure what ExpandProperty parameter does? Check out my blog post on ExpandProperty parameter).
Just like you have EnumKey, there is also an EnumValue method, which lists the Valuenames in a particular key.
I think this post would remain incomplete if I didn't mention Invoke-WMIMethod cmdlet. Since we are calling static methods on the WMI class, we can also use Invoke-WMIMethod to call all the methods we have discussed in this post. I want to give you one example of using the Invoke-WMIMethod (to call EnumValues method). Just like we could call EnumValues, we can call any of the methods we have discussed in this blogpost.
According to me, one of the most important advantage offered by these cmdlets (Get-WMIObject and Invoke-WMIMethod) is that you have a -ComputerName and a -Credential parameter. That means you can connect to a remote machine using different credentials when you are using these WMI cmdlets.
Hopefully, this post gave you a good enough idea of how to interact with the registry on local or remote machine using WMI. Using this class you can create as well as delete keys or values. Doing a Get-Member along with a Format-Table -Wrap on the output will give you a good enough understanding of leveraging the different methods further. Just keep in mind that whenever you see hDefKey (Int32) parameter for any of these methods, you are supposed to pass the numeric value of a registry hive to that method.
This approach should be useful if you want to interact with registry on remote machines and don't have PowerShell v2 Remoting enabled on your remote machine yet. If you have PowerShell v2 Remoting enabled, its just about using *-Item and *-ItemProperty related cmdlets to interact with the Registry instead of doing this!
Comments
Anonymous
August 12, 2015
Hi, I need to set a WMI filter for a GPO. The filter should allow us to be able to apply GPO to machines with a exact value match. Is there a way for us to do that?Anonymous
September 04, 2015
Just wanted to tell you that after reading article after article on this topic, I finally found your write up. It helped me accomplish fix an issue that had been causing me some trouble by explaining plainly a topic I only half grasped. Thank you for that.