Thursday, September 22, 2011

Using PowerShell and WMI to Manage the Registry

For those of you who are very keen eyed, you may have noticed some posts on my PowerShell Scripts blog related to the WMI Registry Provider. I’ve been working on a PowerShell and WMI course which will be published by Plural Sight in October. As part of this, I have been playing with WMI and the Registry provider, which you can easily use via PowerShell.

Microsoft has implemented a nice registry provider withing WMI: the StdRegProv class in the ROOT\DEFAULT WMI class.  This class contains 20 static methods that enable you to perform any Registry action on a local or remote computer. You can access these in two ways, either using New-Object to create a new System.Management.ManagementClass object, specifying the path to the class to the constructor ("Root\default:StdRegProv"). Alternatively, you could use the [WmiClass] Type Accelerator, specifying [WmiClass]"Root\default:StdRegProv". Both return the class object, which contains a number of methods as shown here:

c:\> $x=new-object System.Management.ManagementClass "Root\default:StdRegProv"
c:\> $x.Methods | ft name

Name                                                 
----                                            
CreateKey                                                
DeleteKey                                                
EnumKey                                                  
EnumValues                                                
DeleteValue                                                
SetDWORDValue                                                
SetQWORDValue                                                
GetDWORDValue                                                
GetQWORDValue                                                  
SetStringValue                                                 
GetStringValue                                                 
SetMultiStringValue                                                
GetMultiStringValue                                                 
SetExpandedStringValue                                                
GetExpandedStringValue                                                 
SetBinaryValue                                                
GetBinaryValue                                                
CheckAccess                                                 
SetSecurityDescriptor           
GetSecurityDescriptor   

In effect you have four sets of methods:

  • Create/delete registry key (CreateKey, DeleteKey)
  • Enumerate a registry key or value entry (EnumKey, EnumValue)
  • Create, set or delete a value entry (Set<valuetype>Value, Get<valuetype>Value, DeleteValue)
  • Check security on a value/key (Check Access, SetAccessDescriptor, GetSDecurityDescriptor)

Each method is very easy to call, as you will have seen on my PshScripts blog. To manipulate the registry, you need to specfiy a registry Hive, a Registry Key, and where needed, a registry value. So to create a registry key, you could do this:

$HKEY_LOCAL_MACHINE = 2147483650
$Reg                = [WMIClass]"ROOT\DEFAULT:StdRegProv"
$Key                = "SOFTWARE\NewKey"
$Results            = $Reg.CreateKey($HKEY_LOCAL_MACHINE, $Key) 

In this case, you specify the  hive to create the key in by specifying a well known value, in case, 2147483650. The well known values are as follows:

HKEY_CLASSES_ROOT     2147483648
HKEY_CURRENT_USER     2147483649
HKEY_LOCAL_MACHINE    2147483650
HKEY_USERS            2147483651
HKEY_CURRENT_CONFIG   2147483653
HKEY_DYN_DATA         2147483654
With PowerShell, you first instantiate the class instance, which gets you an object on the local or remote machine. Then, you pass the static methods of htios class the values necessary. You always need to the specific well known numbers – in my example above, via a variable to the call the appropriate registry operation. The other paramaeters will depend on the specific call being made.
 
So to create a new MultiString regisgry value, below the key created earlier, you could do this:

$HKEY_LOCAL_MACHINE = 2147483650
$reg       = [WMIClass]"ROOT\DEFAULT:StdRegProv"
$Key       = "SOFTWARE\NewKey"
$ValueName = "Example MultiString Value"
$Values    = @("Thomas", "Susan", "Rebecca")
$Key       = "SOFTWARE\NewKey"
$reg.SetMultiStringValue($HKEY_LOCAL_MACHINE, $Key, $ValueName, $Values)

In this case, the code created a new MultiString value. There are no explicitly NEW methods on StdRegProv – you use a Set* method to either create a new value entry or change a value. With both getting and setting value entries, you use different methods depending on the specific value type you wish to manage (String, Multi—String, Binary, etc).  With removing a value, there’s only one method: DeleteValue.
 
One small thing to be careful of, DeleteKey, deletes the key specified and everything below it. So Deleting a key of “\” in most of the well known hives is probably not advisable.
 
All in all, it’s darn easy to use the StdRegProv class with PowerShell for all your registry manipulation needs.
Technorati Tags: ,,
 
 

4 comments:

Shay Levy said...

You should check the Remote Registry module :)

http://psremoteregistry.codeplex.com/

Thomas Lee said...

The Remote Registry module, like a lot of 3rd party modules is wnnderful in it's place. I am increasingly coming across customers who have a 'no third party software in our data centre' policy that rules out any other non-MS software no matter how good.
Cool thingS about WMI include that a) it's there in the box and b) being based on WMI all the security issues are probably already worked out and c) it's on by default. So you can use it out of the box and it works withough any third party stuff, or any new GPOs to turn things on (c/f remoting where you need to turn on winrm).

Unknown said...

Thomas,

Thanks for the article, definitely the best how to guide I've seen for using WMI to update the registy. I needed to write some keys to support PSRemoting and this came in handy.

Thomas Lee said...

Jason - glad this was helpful!