Remote Registry Reading the VBScript Way

Last week I blogged about using REG.EXE in a batch file to read a registry key. The batch file I provided works, but the output is limited. You could probably parse it a bit more to get it in some other format. But I’d probably turn to VBScript and WMI if I wanted better output control or if I had more complicated needs.

Without resorting to third party controls, you need to use the WMI registry provider to access remote registries.

strComputer=”localhost”

Set objReg=GetObject(“winmgmts:{impersonationLevel=impersonate}!\” &_
strComputer & “\root\default:StdRegProv”)

Once you have a connection you can enumerate keys or values. I’m going to look at the method for enumerating values since my goal is to read a specified key.

Const HKEY_LOCAL_MACHINE = &H80000002

‘the registry path to query
strKeyPath =”Software\Microsoft\Windows NT\CurrentVersion”
‘the registry key value to get
strValueName=”RegisteredOwner”

objReg.EnumValues HKEY_LOCAL_MACHINE, strKeyPath, arrValues, arrTypes

The EnumValues method takes several parameters: the registry hive to connect to (I’m using a constant value), the registry path, and two variables for the output. The first will store all values found in the registry path and the second will store the type of each value. This is important.

Registry keys can be of different types such as REG_SZ. You need to know the type so you can call the appropriate method. There are different methods depending on the type. The types returned will be numeric so I prefer to use constants

Const REG_SZ = 1
Const REG_EXPAND_SZ = 2
Const REG_BINARY = 3
Const REG_DWORD = 4
Const REG_MULTI_SZ = 7

You’ll see how I use these in a moment.

Suppose I determine that the key I want to read is a string, then I’ll need to use a line like this:

objReg.GetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue

The last parameter,I’m using strValue, is the variable that will hold the method’s result. All that’s left at this point is to display the contents of strValue

wscript.echo strValue

I’ve created a VBScript you can use to make the whole process a little easier (it is also attached as a text file).

’ NAME: ReadRegistry.vbs
’ VERSION: 1.0 2/7/2008
’ AUTHOR: Jeffery Hicks jhicks@sapien.com
’ USAGE: cscript ReadRegistry [/s:computername]

’ DESCRIPTION: Use the WMI registry provider to read a remote
’ registry key value. If you don’t specify a computer name the script
’ will default to localhost.

‘ *********************************************************************************
‘ * THIS PROGRAM IS OFFERED AS IS AND MAY BE FREELY MODIFIED OR ALTERED AS *
‘ * NECESSARY TO MEET YOUR NEEDS. THE AUTHOR MAKES NO GUARANTEES OR WARRANTIES, *
‘ * EXPRESS, IMPLIED OR OF ANY OTHER KIND TO THIS CODE OR ANY USER MODIFICATIONS. *
‘ * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED IN A SECURED LAB *
‘ * ENVIRONMENT. USE AT YOUR OWN RISK. *
‘ *********************************************************************************

On Error Resume Next

Const HKEY_LOCAL_MACHINE = &H80000002
Const REG_SZ = 1
Const REG_EXPAND_SZ = 2
Const REG_BINARY = 3
Const REG_DWORD = 4
Const REG_MULTI_SZ = 7

‘the registry path to query
strKeyPath =”Software\Microsoft\Windows NT\CurrentVersion”
‘the registry key value to get
strValueName=”RegisteredOwner”

If WScript.Arguments.Named.Exists(“S”) Then
strComputer=UCase(WScript.Arguments.Named.Item(“S”))
Else
strComputer = “LOCALHOST”
End If

Set objReg=GetObject(“winmgmts:{impersonationLevel=impersonate}!\” &_
strComputer & “\root\default:StdRegProv”)
If Err.Number 0 Then
strMsg=”There was a problem connecting to ” &_
strComputer & “\root\default:StdRegProv” & VbCrLf &_
“Error ” & Err.Number & ” ” & Err.description
WScript.Echo strMsg
WScript.Quit
End If
objReg.EnumValues HKEY_LOCAL_MACHINE, strKeyPath, arrValues, arrTypes
For x=0 To UBound(arrValues)-1
if Ucase(arrValues(x)) = UCase(strValueName) Then

Select Case arrTypes(x)
Case REG_SZ
objReg.GetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
Case REG_EXPAND_SZ
objReg.GetExpandedStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
Case REG_BINARY
objReg.GetBinaryValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
Case REG_DWORD
objReg.GetDWORDValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
Wscript.Echo
Case REG_MULTI_SZ
objReg.GetMultiStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
End Select
End If

Next

If VarType(strValue)=0 Then
WScript.Echo “Failed to get a value for ” & strKeyPath & strValueName &_
” on ” & strComputer & “. Check your registry keys and permissions.”
Else
If IsArray (strValue) Then
WScript.Echo strComputer & ” – ” & strValueName
For Each value In strValue
WScript.Echo value
Next
Else
WScript.Echo strComputer & ” – ” & strValueName & ” = ” & strValue
End If
End If

‘EOF

You’ll need to edit the file for the registry path and key that you want to read. HKLM is really the only remote hive you can read. The script can take a computer name as a run time parameter:

cscript readregistry /s:server01

If you don’t specify a computer name the script will default to Localhost.

The script connects to the remote registry and enumerates all values in the specified path. It then enumerates the collection (arrValues) looking for the value that matches the specified key

For x=0 To UBound(arrValues)-1
if Ucase(arrValues(x)) = UCase(strValueName) Then

If it is found, the script checks the data type using a Select Case statement

Select Case arrTypes(x)

Depending on the case, the appropriate method is called to read the value:

Case REG_SZ
objReg.GetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
Case REG_EXPAND_SZ
objReg.GetExpandedStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
Case REG_BINARY
objReg.GetBinaryValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
Case REG_DWORD
objReg.GetDWORDValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
Wscript.Echo
Case REG_MULTI_SZ
objReg.GetMultiStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue

At this point all that remains is to display the result. It is possible that the value might be an array as in the case of a multi-string or binary value so I’ll have to check for that and handle it accordingly:

If IsArray (strValue) Then
WScript.Echo strComputer & ” – ” & strValueName
For Each value In strValue
WScript.Echo value
Next
Else
WScript.Echo strComputer & ” – ” & strValueName & ” = ” & strValue
End If

My output is pretty simple, but obviously you could do what ever you wanted with it.

That’s it for now. I have one more idea to explore on this topic so stay tuned.

Technorati Tags: , , , ,