64-bit,MDT2010,Register,VBScript,Windows 7

Läsa och skriva 64-bit register från 32-bit.

Har nyligen haft ett problem då jag var tvungen att läsa och skriva 64-bit register. Ett scenario som jag hade var att vi ville skapa en unik nyckel under HKEY_LOCAL_MACHINE\Software\ och sedan via GPO och ett VMI-filter slå igång off-line folder om den som loggade på var den som var managedBy i Active Directory. WMI- filtret körs som 64-bit men scriptet som skapade nycklarna i registret gick som 32-bit.

Jag var tvungen att skapa och läsa 64-bit register men programmet kördes i 32-bit och då kan man inte normalt läsa/skriva i 64-bits register. Efter lite forskande på nätet så kom jag fram till att jag kan lösa detta via VMI. Med hjälp av StdRegProv klassen som innehåller metoder som man kan manipulerar systemets registernycklar och värden. StdRegProv är för installerat i WMI namnrymderna root\default och root\cimv2.

Värt att notera är att X64 versionen av Windows inte rakt av kan köra 32-bitars kod. Eftersom de flesta program är 32-bitars kommer x64 versionen av Windows att använda emulator som kallas WOW64, för att tillåta 32-bitars applikationer att köras. Ett av problemen med att köra 32-bitars kod på en 64-bitars operativsystem är att OS ska upprätthålla fullständig kod separation. Microsoft har skapat en ny mapp med namnet \Windows\SysWOW64 som används för att lagra 32-bitars DLL-filer. I 32-bitarsversionen av Windows, är DLL-filer normalt lagras i \windows\system32-mappen. Dock använder x64-versionen av Windows mappen \Windows\System32-mappen för 64-bitars DLL-filer.

Som standard får ett program eller skript data från motsvarande provider när två versioner av providern finns. 32-bitars provider återvänder data till ett 32-bitars program, inklusive alla skript, och 64-bitars provider returnerar data till 64-bitars kompilerade applikationer. Däremot kan ett program eller skript begära data från icke standard provider, om den finns, genom att meddela WMI genom flaggor på metodanrop.

Genom att använda flaggan __ProviderArchitecture kan man begära tillgång till 32-bitars register i en 64-bitars dator. Den som anropar kopplas till 32-bitars hive oavsett om det är en 32 – eller 64-bitars program.

Problemet jag fick var att jag inte kunde komma åt ett 64-bits register värde då script jag körde exekverades som 32-bit via sccm klienten. Men genom att använda __ProviderArchitecture och StdRegProv kom jag runt detta.
Naturligt vis kan man göra tvärt om och läsa och skriva 32-bits registret från en 64-bits 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

För att testa scriptet så kan man starta ett 32-bitars kommando tolk så här:

Klicka på Start, Kör, skriv% windir% \ syswow64 \ cmd.exe och klicka på OK.
skriv sedan i fönstret:

cscript registry_64.vbs

Läs mer

MDT2010,SCCM 2007,Windows PE

Svensk Tangentbords i Windows PE

Har alltid haft problem med att få svensk tangentbord i Windows PE. Letade på webben och hittade då att man skall använda följande i Bootstrap.ini.

KeyboardLocalePE=041d:0000041d

Läs mer