Poster taggade ‘MDT2010’

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

MDT2010,VBScript

VB Script för att flytta filer vid emigrering av användare från XP till Windows 7

Håller på att skriva ett VB-script som skall flytta användarens dokument i hemkatalogen till en Subfolder ”Mina dokument” som ligger som folder re-direct i Windows 7 samt kommer att finnas som tillgänglig i off-line läge.
Är ingen expert på detta men det verkar fungera. Uppdaterad till ny version.

Option Explicit

Dim objFSO
Dim StrDrive
Dim folderobj
Dim FromFolder
Dim ToFolder
Dim FromPath
Dim ToPath
Dim objSubfolder
Dim colSubFolders 
Dim dicSelFolders
Dim FolderToMoveFrom
Dim FolderToMoveTo
Dim Files
Dim OneFile
Dim FileInFromFolder
Dim Fileset
Dim SourceFileName
Dim DestFileName
Dim FileCount
Dim DestFile
Dim DocFolderExist

StrDrive = "F"
FromFolder = ""
ToFolder = "Mina dokument"

Strdrive=UCase(Left(StrDrive,1)) & ":\"

Set objFSO        = CreateObject( "Scripting.FileSystemObject" )
Set FromPath      = objFSO.GetFolder( StrDrive & FromFolder )
Set ToPath        = objFSO.GetFolder( StrDrive & ToFolder ) 
Set colSubFolders = FromPath.Subfolders
Set dicSelFolders = CreateObject( "Scripting.Dictionary" )

'Folders not to move
dicSelFolders.Add "$recycle.bin", ""
dicSelFolders.Add "mina dokument", ""
dicSelFolders.Add "program", ""

'if folder does not exist on destination drive,
' create it and continue

If Not objFSO.FolderExists(StrDrive & "\" & ToFolder) Then
   'WScript.Echo  "Normal run"
   objFSO.CreateFolder StrDrive & ToFolder
   MoveUserFolders()
   MoveUserFiles()
Else
   'WScript.Echo "Rename Mina dokument"
   objFSO.MoveFolder StrDrive & ToFolder, StrDrive & "Gamla " & ToFolder
   objFSO.CreateFolder StrDrive & ToFolder
   MoveUserFolders()
   MoveUserFiles()
End If

Wscript.Quit

Sub MoveUserFolders()

For Each objSubfolder in colSubfolders

If dicSelFolders.Exists( LCase( objSubfolder.Name ) ) Then
   'WScript.Echo "Leaving Folder", objSubfolder.Path
Else
   'WScript.Echo "Moving Folder", objSubfolder.Path
   If FromFolder = "" Then
      FolderToMoveFrom = FromPath & objSubfolder.Name
   Else
      FolderToMoveFrom = FromPath & "\" & objSubfolder.Name
   End If
   FolderToMoveTo = ToPath & "\" & objSubfolder.Name
   objFSO.MoveFolder FolderToMoveFrom, FolderToMoveTo
End If
Next

End Sub

Sub MoveUserFiles()

Set Fileset = FromPath.Files

'if no more subfolders, then go through files
For Each OneFile in Fileset
  SourceFileName = FromPath & "\" & OneFile.name
  DestFileName = ToPath & "\" & OneFile.name

  'if the destination file doesn't exist,
  'then copy the sourcefile to the destination folder
  If Not objFSO.FileExists(DestFileName) Then
    On Error Resume Next
    OneFile.Copy DestFileName
    OneFile.Delete
    On Error GoTo 0
    FileCount = FileCount + 1
  'if the destination file already exists
  Else
    Set DestFile=objFSO.GetFile(DestFileName)
    
    'then check to see if the source file's last modified date
    'is newer than the destination file. If it is,
    'then overwrite the destination file with the source file
    If onefile.DateLastModified > destfile.DateLastModified Then
      'turn all file attributes off to copy updated file over older one
      DestFile.Attributes = 0
      On Error Resume Next
      onefile.Copy DestFileName, True
      On Error GoTo 0
      OneFile.Delete
      FileCount = FileCount + 1
    End If
    Set destfile=Nothing
  End If
Next

End sub

Läs mer