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.
1 Option Explicit 2 3 '--------------------------------------------------- 4 ' Declared Constants 5 '--------------------------------------------------- 6 7 Const wbemFlagReturnImmediately = &h10 8 Const wbemFlagForwardOnly = &h20 9 Const Success = 0 10 Const Failure = 1 11 Const HKEY_LOCAL_MACHINE = &H80000002 12 Const Read_REG_SZ = "GetStringValue" 13 Const Write_REG_SZ = "SetStringValue" 14 Const Read_REG_DWORD = "GetDWORDValue" 15 Const Write_REG_DWORD = "SetDWORDValue" 16 17 '--------------------------------------------------- 18 ' Declared Variables 19 '--------------------------------------------------- 20 21 Dim strResult, TextString1, TextString2 22 23 '--------------------------------------------------- 24 ' Parameters for Funktions ReadRegStr and WriteRegStr 25 '--------------------------------------------------- 26 27 ' Reads a REG_SZ and REG_DWORD value from the local computer's registry using WMI. 28 ' Parameters: 29 ' Method - What type of value going to write (GetStringValue, SetStringValue, GetDWORDValue, SetDWORDValue) 30 ' RootKey - The registry hive (HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CURRENT_CONFIG 31 ' Key - The key that contains the desired value. 32 ' Value - The value that you want to get. 33 ' RegType - The registry bitness: 32 or 64 34 35 '--------------------------------------------------- 36 ' Create _TEST registry key in 64-bit Registry 37 '--------------------------------------------------- 38 39 WScript.Echo "---------------------------------------------------" 40 WScript.Echo " Creating _TEST key in 64-bit Registry " 41 WScript.Echo "---------------------------------------------------" 42 43 strResult = CreateRegKey (HKEY_LOCAL_MACHINE, "Software\_TEST", 64) 44 45 If strResult = 0 Then 46 WScript.Echo "Able to Create Key : " & "HKEY_LOCAL_MACHINE\Software\_TEST" 47 Else 48 WScript.Echo "Not able to Create Key" 49 'WScript.Quit 50 End If 51 52 '--------------------------------------------------- 53 ' Set _TEST registry values in 64-bit Registry 54 '--------------------------------------------------- 55 56 WScript.Echo "---------------------------------------------------" 57 WScript.Echo " Writing in 64-bit Registry " 58 WScript.Echo "---------------------------------------------------" 59 60 ' Writing Testvalue1 61 TextString1 = "Test of writing value 1" 62 strResult = WriteRegStr (Write_REG_SZ, HKEY_LOCAL_MACHINE, "Software\_TEST", "SubKey1", TextString1, 64) 63 64 If strResult = 0 and debug = 1 Then 65 WScript.Echo "Able to Write Value : " & "SubKey1" & " = "& TextString1 66 Else 67 WScript.Echo "Not able to Write Value" 68 'WScript.Quit 69 End If 70 71 ' Writing Testvalue2 72 TextString2 = "Test of writing value 2" 73 strResult = WriteRegStr (Write_REG_SZ, HKEY_LOCAL_MACHINE, "Software\_TEST", "SubKey2", TextString2, 64) 74 75 If strResult = 0 Then 76 WScript.Echo "Able to Write Value : " & "SubKey2" & " = "& TextString2 77 Else 78 WScript.Echo "Not able to Write Value" 79 'WScript.Quit 80 End If 81 82 '--------------------------------------------------- 83 ' Delete a SubKey value in 64-bit Registry 84 '--------------------------------------------------- 85 86 strResult = DeleteSubKeyValue (HKEY_LOCAL_MACHINE, "Software\_TEST", "SubKey1", 64) 87 88 If strResult = 0 Then 89 WScript.Echo "Able to Delete SubKey value : " & "HKEY_LOCAL_MACHINE\Software\_TEST\SubKey1" 90 Else 91 WScript.Echo "Not able to Delete SubKey value" 92 'WScript.Quit 93 End If 94 95 '--------------------------------------------------- 96 ' Delete _TEST registry key in 64-bit Registry 97 '--------------------------------------------------- 98 99 WScript.Echo "---------------------------------------------------" 100 WScript.Echo " Delete _TEST key in 64-bit Registry " 101 WScript.Echo "---------------------------------------------------" 102 103 strResult = DeleteRegKey (HKEY_LOCAL_MACHINE, "Software\_TEST", 64) 104 105 If strResult = 0 Then 106 WScript.Echo "Able to Delete Key : " & "HKEY_LOCAL_MACHINE\Software\_TEST" 107 Else 108 WScript.Echo "Not able to Delete Key" 109 'WScript.Quit 110 End If 111 112 '--------------------------------------------------- 113 ' Function Create Registry Key 114 '--------------------------------------------------- 115 116 Function CreateRegKey(RootKey, KeyPath, RegType) 117 118 Dim oCtx, oLocator, oReg, oInParams, oOutParams 119 Dim strKeyPath, Return 120 121 Set oCtx = CreateObject("WbemScripting.SWbemNamedValueSet") 122 oCtx.Add "__ProviderArchitecture", RegType 123 124 Set oLocator = CreateObject("Wbemscripting.SWbemLocator") 125 Set oReg = oLocator.ConnectServer("", "root\default", "", "", , , , oCtx).Get("StdRegProv") 126 127 Set oInParams = oReg.Methods_("CreateKey").InParameters 128 oInParams.hDefKey = RootKey 129 oInParams.sSubKeyName = KeyPath 130 131 Set oOutParams = oReg.ExecMethod_("CreateKey", oInParams, , oCtx) 132 133 CreateRegKey = oOutParams.ReturnValue 134 135 set oCtx = Nothing 136 set oLocator = Nothing 137 138 End Function 139 140 '--------------------------------------------------- 141 ' Function Delete Registry Key 142 '--------------------------------------------------- 143 144 Function DeleteRegKey(RootKey, KeyPath, RegType) 145 146 Dim oCtx, oLocator, oReg, oInParams, oOutParams 147 Dim strKeyPath, Return 148 149 Set oCtx = CreateObject("WbemScripting.SWbemNamedValueSet") 150 oCtx.Add "__ProviderArchitecture", RegType 151 152 Set oLocator = CreateObject("Wbemscripting.SWbemLocator") 153 Set oReg = oLocator.ConnectServer("", "root\default", "", "", , , , oCtx).Get("StdRegProv") 154 155 Set oInParams = oReg.Methods_("DeleteKey").InParameters 156 oInParams.hDefKey = RootKey 157 oInParams.sSubKeyName = KeyPath 158 159 Set oOutParams = oReg.ExecMethod_("DeleteKey", oInParams, , oCtx) 160 161 DeleteRegKey = oOutParams.ReturnValue 162 163 wscript.echo 164 165 set oCtx = Nothing 166 set oLocator = Nothing 167 168 End Function 169 170 '--------------------------------------------------- 171 ' Function Read Registry String 172 '--------------------------------------------------- 173 174 Function ReadRegStr (Method, RootKey, Key, Value, RegType) 175 Dim oCtx, oLocator, oReg, oInParams, oOutParams 176 177 Set oCtx = CreateObject("WbemScripting.SWbemNamedValueSet") 178 oCtx.Add "__ProviderArchitecture", RegType 179 180 Set oLocator = CreateObject("Wbemscripting.SWbemLocator") 181 Set oReg = oLocator.ConnectServer("", "root\default", "", "", , , , oCtx).Get("StdRegProv") 182 183 Set oInParams = oReg.Methods_(Method).InParameters 184 oInParams.hDefKey = RootKey 185 oInParams.sSubKeyName = Key 186 oInParams.sValueName = Value 187 188 Set oOutParams = oReg.ExecMethod_(Method, oInParams, , oCtx) 189 190 ReadRegStr = oOutParams.sValue 191 192 set oCtx = Nothing 193 set oLocator = Nothing 194 End Function 195 196 '--------------------------------------------------- 197 ' Function Write Registry String 198 '--------------------------------------------------- 199 200 Function WriteRegStr (Method, RootKey, Key, ValueName, Value, RegType) 201 202 Dim oCtx, oLocator, oReg, oInParams, oOutParams 203 204 Set oCtx = CreateObject("WbemScripting.SWbemNamedValueSet") 205 oCtx.Add "__ProviderArchitecture", RegType 206 207 Set oLocator = CreateObject("Wbemscripting.SWbemLocator") 208 Set oReg = oLocator.ConnectServer("", "root\default", "", "", , , , oCtx).Get("StdRegProv") 209 210 Set oInParams = oReg.Methods_(Method).InParameters 211 oInParams.hDefKey = RootKey 212 oInParams.sSubKeyName = Key 213 oInParams.sValueName = ValueName 214 oInParams.sValue = Value 215 216 Set oOutParams = oReg.ExecMethod_(Method, oInParams, , oCtx) 217 218 WriteRegStr = oOutParams.ReturnValue 219 220 Set oCtx = Nothing 221 Set oLocator = Nothing 222 223 End Function 224 225 '--------------------------------------------------- 226 ' Function Delete Registry value 227 '--------------------------------------------------- 228 229 Function DeleteSubKeyValue (RootKey, KeyPath, ValueName, RegType) 230 231 Dim oCtx, oLocator, oReg, oInParams, oOutParams 232 233 Set oCtx = CreateObject("WbemScripting.SWbemNamedValueSet") 234 oCtx.Add "__ProviderArchitecture", RegType 235 236 Set oLocator = CreateObject("Wbemscripting.SWbemLocator") 237 Set oReg = oLocator.ConnectServer("", "root\default", "", "", , , , oCtx).Get("StdRegProv") 238 239 Set oInParams = oReg.Methods_("DeleteValue").InParameters 240 oInParams.hDefKey = RootKey 241 oInParams.sSubKeyName = KeyPath 242 oInParams.sValueName = ValueName 243 244 Set oOutParams = oReg.ExecMethod_("DeleteValue", oInParams, , oCtx) 245 246 DeleteSubKeyValue = oOutParams.ReturnValue 247 248 Set oCtx = Nothing 249 Set oLocator = Nothing 250 251 End Function