Remote registry access and creating new Registry values with PowerShell
I got a question from a reader by mail about remote registry access, how to create new properties remote and how to specify the Kind of value it needed to be e.g. REG_SZ or REG_BINARY he could access the remote registry key with :
$MachineName = '.'
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $MachineName)
connect to the needed key :
$regKey= $reg.OpenSubKey("SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation" )
and list the properties :
$regkey.GetValueNames()
but was confused about how to go on from there creating new properties,
he did find a createSubkey() to create new subkeys but no method to create properties, a CreateProperty() method for example.
As the problem was well described, deserved a thorough anwer and as I did think this info can also be useful to other readers of my blog, I post my answer here on my blog :
How to create new values on a remote registry
the answer to this question is very simple but there are 2 things to take in account :
On my old blog I show how to change a registry value remotely : /\/\o\/\/ PowerShelled: StartRDP script but not how to create new Registry values remotely , but it is almost the same :
- The same method is used to create and change values SetValue() if the value does not exist yet it is created, and you can give the Kind of value as an parameter
in the old post I show also another caveat,
- standard registry keys are opened in Read Only mode, you need to enable write mode first
after mastering this for the rest it is very simple to show how it works let's follow the example :
Open the Key in Read-Write mode :
PoSH> $MachineName = '.'
PoSH> $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $MachineName)
PoSH> $regKey= $reg.OpenSubKey("SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation")
PoSH> $regkey.GetValueNames()
Bias
StandardName
StandardBias
StandardStart
DaylightName
DaylightBias
DaylightStart
TimeZoneKeyName
DynamicDaylightTimeDisabled
ActiveTimeBias
PoSH> $regkey.SetValue('foo','bar')
Exception calling "SetValue" with "2" argument(s): "Cannot write to the registry key."
At line:1 char:17
+ $regkey.SetValue( <<<< 'foo','bar')
PoSH>
You see we get an error here, that the key is readonly,
as mentioned on my old blog you can change that by adding $true as a second parameter, we can see this as use the method name without the parentheses by this overload
OpenSubKey(String name, Boolean writable), :
PoSH> $reg.OpenSubKey
MemberType : Method
OverloadDefinitions : {Microsoft.Win32.RegistryKey OpenSubKey(String name, Boolean writable), Micro
soft.Win32.RegistryKey OpenSubKey(String name), Microsoft.Win32.RegistryKey O
penSubKey(String name, RegistryKeyPermissionCheck permissionCheck), Microsoft
.Win32.RegistryKey OpenSubKey(String name, RegistryKeyPermissionCheck permiss
ionCheck, RegistryRights rights)}
TypeNameOfValue : System.Management.Automation.PSMethod
Value : Microsoft.Win32.RegistryKey OpenSubKey(String name, Boolean writable), Micros
oft.Win32.RegistryKey OpenSubKey(String name), Microsoft.Win32.RegistryKey Op
enSubKey(String name, RegistryKeyPermissionCheck permissionCheck), Microsoft.
Win32.RegistryKey OpenSubKey(String name, RegistryKeyPermissionCheck permissi
onCheck, RegistryRights rights)
Name : OpenSubKey
IsInstance : True
PoSH> $regKey= $reg.OpenSubKey("SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation",$true)
PoSH> $regkey.SetValue('foo','bar')
PoSH> $regkey.GetValueNames()
Bias
StandardName
StandardBias
StandardStart
DaylightName
DaylightBias
DaylightStart
TimeZoneKeyName
DynamicDaylightTimeDisabled
ActiveTimeBias
foo
PoSH>
Create new Property and Set the Value
You can see that I could now set the Property foo with the value bar even as it did not exist yet, so in effect creating a new registry value this was, but how to specify the kind of registry value ?
If we check the overloads on the SetValue method we see that it has an overload that takes a RegistryValueKind type
PoSH> $regkey.SetValue
MemberType : Method
OverloadDefinitions : {System.Void SetValue(String name, Object value), System.Void SetValue(String
name, Object value, RegistryValueKind valueKind)}
TypeNameOfValue : System.Management.Automation.PSMethod
Value : System.Void SetValue(String name, Object value), System.Void SetValue(String
name, Object value, RegistryValueKind valueKind)
Name : SetValue
IsInstance : True
PoSH> $regkey.SetValue('foo','bar','foo')
Cannot convert argument "2", with value: "foo", for "SetValue" to type "Microsoft.Win32.RegistryVal
ueKind": "Cannot convert value "foo" to type "Microsoft.Win32.RegistryValueKind" due to invalid enu
meration values. Specify one of the following enumeration values and try again. The possible enumer
ation values are "Unknown, String, ExpandString, Binary, DWord, MultiString, QWord"."
At line:1 char:17
+ $regkey.SetValue( <<<< 'foo','bar','foo')
PoSH> $regkey.SetValue('foo','bar','string')
PoSH>
And by making an error you can see that you can specify the following kind of values :
Unknown
String
ExpandString
Binary
DWord
MultiString
QWord
* Tip * PowerTab users can just do :
get-tabExpansion *RegistryValueKind* types
Add-TabExpansionEnum Microsoft.Win32.RegistryValueKind
or :
Add-TabExpansionEnumFromLastError
*edit* not to forget [Microsoft.Win32.RegistryValueKind]: [tab] or ::[tab]
And we can create the valueKind we need be giving this ValueKind as a string to setValue() as the third parameter.
That's all you have to know, the remote registry is at your full command now from your PoSH console ;-)
Enjoy,
Greetings /\/\o\/\/