Have recently had a problem when I had to read and write 64-bit registry. One scenario I had was that we wanted to create a unique key under HKEY_LOCAL_MACHINE \ Software \ and then via GPO and a VMI filter, turn off offline folders about who logged in was who was managedBy in Active Directory. The WMI filter runs as 64-bit but the script that created the keys in the registry went as 32-bit.

I had to create and read 64-bit registry but the program was run in 32-bit and then you can not normally read / write in 64-bit registry. After some research online, I realized that I can solve this via VMI. Using the StdRegProv class containing methods that you can manipulate the system registry keys and values. StdRegProv is too installed in WMI namespaces root \ default and root \ cimv2.

Worth noting is that the X64 version of Windows can not run correctly 32-bit code. Since most programs are 32-bit, the x64 version of Windows will use emulator called WOW64, to allow 32-bit applications to run. One of the problems of running 32-bit code on a 64-bit operating system is that the OS should maintain full code separation. Microsoft has created a new folder named \ Windows \ SysWOW64 that is used to store 32-bit DLL files. In the 32-bit version of Windows, DLL files are normally stored in the \ windows \ system32 folder. However, the x64 version of Windows uses the \ Windows \ System32 folder folder for 64-bit DLL files.

By default, a program or script gets data from the corresponding provider when there are two versions of the provider. 32-bit provider returns data to a 32-bit application, including all scripts, and 64-bit provider returns data to 64-bit compiled applications. However, a program or script may request non-standard provider data, if available, by notifying WMI through methodological flags.

By using the __ProviderArchitecture flag, you can request access to 32-bit records in a 64-bit computer. The caller connects to 32-bit hive, whether it’s a 32- or 64-bit program.

The problem I received was that I could not access a 64-bit registry value when the script I was running was executed as 32-bit via the sccm client. But using __ProviderArchitecture and StdRegProv I came around this.
Naturally, one can reverse and read and write the 32-bit registry from a 64-bit session.

Option Explicit

'---------------------------------------------------
' Declared Constants 
'---------------------------------------------------

Const wbemFlagReturnImmediately = &h10 
Const wbemFlagForwardOnly = &h20
Const Success = 0
Const Failure = 1
Const HKEY_LOCAL_MACHINE = &H80000002
Const Read_REG_SZ = "GetStringValue"
Const Write_REG_SZ = "SetStringValue"
Const Read_REG_DWORD = "GetDWORDValue"
Const Write_REG_DWORD = "SetDWORDValue"

'---------------------------------------------------
' Declared Variables 
'---------------------------------------------------

Dim strResult, TextString1, TextString2

'---------------------------------------------------
' Parameters for Funktions ReadRegStr and WriteRegStr
'---------------------------------------------------

' Reads a REG_SZ and REG_DWORD value from the local computer's registry using WMI. 
' Parameters:
' Method - What type of value going to write (GetStringValue, SetStringValue, GetDWORDValue, SetDWORDValue)
' RootKey - The registry hive (HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CURRENT_CONFIG
' Key - The key that contains the desired value. 
' Value - The value that you want to get. 
' RegType - The registry bitness: 32 or 64

'---------------------------------------------------
' Create _TEST registry key in 64-bit Registry
'---------------------------------------------------

WScript.Echo "---------------------------------------------------"
WScript.Echo " Creating _TEST key in 64-bit Registry "
WScript.Echo "---------------------------------------------------"

strResult = CreateRegKey (HKEY_LOCAL_MACHINE, "Software\_TEST", 64)

If strResult = 0 Then
WScript.Echo "Able to Create Key : " & "HKEY_LOCAL_MACHINE\Software\_TEST"
Else
WScript.Echo "Not able to Create Key"
'WScript.Quit
End If

'---------------------------------------------------
' Set _TEST registry values in 64-bit Registry
'---------------------------------------------------

WScript.Echo "---------------------------------------------------"
WScript.Echo " Writing in 64-bit Registry "
WScript.Echo "---------------------------------------------------"

' Writing Testvalue1
TextString1 = "Test of writing value 1"
strResult = WriteRegStr (Write_REG_SZ, HKEY_LOCAL_MACHINE, "Software\_TEST", "SubKey1", TextString1, 64)

If strResult = 0 and debug =  1 Then
WScript.Echo "Able to Write Value : " & "SubKey1" & " = "& TextString1
Else
WScript.Echo "Not able to Write Value"
'WScript.Quit
End If

' Writing Testvalue2
TextString2 = "Test of writing value 2"
strResult = WriteRegStr (Write_REG_SZ, HKEY_LOCAL_MACHINE, "Software\_TEST", "SubKey2", TextString2, 64)

If strResult = 0 Then
WScript.Echo "Able to Write Value : " & "SubKey2" & " = "& TextString2
Else
WScript.Echo "Not able to Write Value"
'WScript.Quit
End If

'---------------------------------------------------
' Delete a SubKey value in 64-bit Registry
'---------------------------------------------------

strResult = DeleteSubKeyValue (HKEY_LOCAL_MACHINE, "Software\_TEST", "SubKey1", 64)

If strResult = 0 Then
WScript.Echo "Able to Delete SubKey value : " & "HKEY_LOCAL_MACHINE\Software\_TEST\SubKey1"  
Else
WScript.Echo "Not able to Delete SubKey value"
'WScript.Quit
End If

'---------------------------------------------------
' Delete _TEST registry key in 64-bit Registry
'---------------------------------------------------

WScript.Echo "---------------------------------------------------"
WScript.Echo " Delete _TEST key in 64-bit Registry "
WScript.Echo "---------------------------------------------------"

strResult = DeleteRegKey (HKEY_LOCAL_MACHINE, "Software\_TEST", 64)

If strResult = 0 Then
WScript.Echo "Able to Delete Key : " & "HKEY_LOCAL_MACHINE\Software\_TEST"
Else
WScript.Echo "Not able to Delete Key"
'WScript.Quit
End If

'---------------------------------------------------
' Function Create Registry Key
'---------------------------------------------------

Function CreateRegKey(RootKey, KeyPath, RegType)

Dim oCtx, oLocator, oReg, oInParams, oOutParams 
Dim strKeyPath, Return

Set oCtx = CreateObject("WbemScripting.SWbemNamedValueSet") 
oCtx.Add "__ProviderArchitecture", RegType

Set oLocator = CreateObject("Wbemscripting.SWbemLocator") 
Set oReg = oLocator.ConnectServer("", "root\default", "", "", , , , oCtx).Get("StdRegProv")

Set oInParams = oReg.Methods_("CreateKey").InParameters 
oInParams.hDefKey = RootKey 
oInParams.sSubKeyName = KeyPath 

Set oOutParams = oReg.ExecMethod_("CreateKey", oInParams, , oCtx)

CreateRegKey = oOutParams.ReturnValue

set oCtx = Nothing 
set oLocator = Nothing 

End Function

'---------------------------------------------------
' Function Delete Registry Key
'---------------------------------------------------

Function DeleteRegKey(RootKey, KeyPath, RegType)

Dim oCtx, oLocator, oReg, oInParams, oOutParams 
Dim strKeyPath, Return

Set oCtx = CreateObject("WbemScripting.SWbemNamedValueSet") 
oCtx.Add "__ProviderArchitecture", RegType

Set oLocator = CreateObject("Wbemscripting.SWbemLocator") 
Set oReg = oLocator.ConnectServer("", "root\default", "", "", , , , oCtx).Get("StdRegProv")

Set oInParams = oReg.Methods_("DeleteKey").InParameters 
oInParams.hDefKey = RootKey 
oInParams.sSubKeyName = KeyPath 

Set oOutParams = oReg.ExecMethod_("DeleteKey", oInParams, , oCtx)

DeleteRegKey = oOutParams.ReturnValue

wscript.echo 

set oCtx = Nothing 
set oLocator = Nothing 

End Function

'---------------------------------------------------
' Function Read Registry String
'---------------------------------------------------

Function ReadRegStr (Method, RootKey, Key, Value, RegType) 
Dim oCtx, oLocator, oReg, oInParams, oOutParams 

Set oCtx = CreateObject("WbemScripting.SWbemNamedValueSet") 
oCtx.Add "__ProviderArchitecture", RegType 

Set oLocator = CreateObject("Wbemscripting.SWbemLocator") 
Set oReg = oLocator.ConnectServer("", "root\default", "", "", , , , oCtx).Get("StdRegProv") 

Set oInParams = oReg.Methods_(Method).InParameters 
oInParams.hDefKey = RootKey 
oInParams.sSubKeyName = Key 
oInParams.sValueName = Value 

Set oOutParams = oReg.ExecMethod_(Method, oInParams, , oCtx) 

ReadRegStr = oOutParams.sValue 

set oCtx = Nothing 
set oLocator = Nothing 
End Function

'---------------------------------------------------
' Function Write Registry String
'---------------------------------------------------

Function WriteRegStr (Method, RootKey, Key, ValueName, Value, RegType) 

Dim oCtx, oLocator, oReg, oInParams, oOutParams 

Set oCtx = CreateObject("WbemScripting.SWbemNamedValueSet") 
oCtx.Add "__ProviderArchitecture", RegType 

Set oLocator = CreateObject("Wbemscripting.SWbemLocator") 
Set oReg = oLocator.ConnectServer("", "root\default", "", "", , , , oCtx).Get("StdRegProv") 

Set oInParams = oReg.Methods_(Method).InParameters 
oInParams.hDefKey = RootKey 
oInParams.sSubKeyName = Key 
oInParams.sValueName = ValueName 
oInParams.sValue = Value 

Set oOutParams = oReg.ExecMethod_(Method, oInParams, , oCtx) 

WriteRegStr = oOutParams.ReturnValue

Set oCtx = Nothing 
Set oLocator = Nothing 

End Function

'---------------------------------------------------
' Function Delete Registry value
'---------------------------------------------------

Function DeleteSubKeyValue (RootKey, KeyPath, ValueName, RegType) 

Dim oCtx, oLocator, oReg, oInParams, oOutParams 

Set oCtx = CreateObject("WbemScripting.SWbemNamedValueSet") 
oCtx.Add "__ProviderArchitecture", RegType 

Set oLocator = CreateObject("Wbemscripting.SWbemLocator") 
Set oReg = oLocator.ConnectServer("", "root\default", "", "", , , , oCtx).Get("StdRegProv") 

Set oInParams = oReg.Methods_("DeleteValue").InParameters 
oInParams.hDefKey = RootKey
oInParams.sSubKeyName = KeyPath
oInParams.sValueName = ValueName

Set oOutParams = oReg.ExecMethod_("DeleteValue", oInParams, , oCtx) 

DeleteSubKeyValue = oOutParams.ReturnValue

Set oCtx = Nothing 
Set oLocator = Nothing 

End Function