I am trying to create a registry backup that I can read using VBS. I found a script online that seems to do the trick however, it only goes one file of the Hive deep.
This code:
Const HKEY_CLASSES_ROOT = &H80000000
Const HKEY_CURRENT_USER = &H80000001
Const HKEY_LOCAL_MACHINE = &H80000002
Const HKEY_USERS = &H80000003
Const HKEY_CURRENT_CONFIG = &H80000004
strKeyPath = ""
Sub EnumerateKeys(hive, key, f)
f.WriteLine( key)
reg.EnumKey hive, key, arrSubKeys
If Not IsNull(arrSubKeys) Then
For Each subkey In arrSubKeys
EnumerateKeys hive, key & "\" & subkey, f
Next
End If
End Sub
Set reg = GetObject("winmgmts://./root/default:StdRegProv")
Set fso = CreateObject("Scripting.FileSystemObject")
path = <Path to Text file>
If fso.FileExists(path) Then
Else
Set file = fso.CreateTextFile(path)
End If
EnumerateKeys HKEY_LOCAL_MACHINE, strKeyPath, file
executes to
\BCD00000000
\HARDWARE
\SAM
\SECURITY
\SOFTWARE
\SYSTEM
and only seems to go the first file path deep. Any help would be appreciated.
Thanks
Related
Here is my code:
Const HKEY_CLASSES_ROOT= &H80000000
Const HKEY_CURRENT_USER= &H80000001
Const HKEY_LOCAL_MACHINE= &H80000002
Const HKEY_USERS= &H80000003
Set StdOut = WScript.StdOut
Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
strKeyPath = "SYSTEM\CurrentControlSet\Hardware Profiles\UnitedVideo\CONTROL\VIDEO\{D218E173-A430-11E8-80D8-005056C00008}\0001"
strValueName = "venkat"
oReg.SetDWordValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, 800
oReg.GetDWordValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, dval
WScript.Echo "SYSTEM\CurrentControlSet\Control\" & " = " & dval
I'm running in Windows 10.
SetDWordValue of in the script is not working.
GetDwordValue is working fine and I'm getting the data.
Tried all the possibilities. Even the code from MSDN is not working. I want to change my registry key using vbs.
The most likely reason is that you simply don't have permission to write to that registry key. The WMI registry methods don't raise an error when something goes wrong, so you need to check the method's return code, e.g. by changing the line
oReg.SetDWordValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, 800
to
rc = oReg.SetDWordValue(HKEY_LOCAL_MACHINE, strKeyPath, strValueName, 800)
WScript.Echo rc
A return code of 5 means you have a permission error.
To fix that you probably just need to run the script "as Admin".
the script works on x86 but doesnt create the file on x64.
Can anyone understand why and explain?
The script is searching the registry, Uninstall key and checking for displayname equal to what im searching for, and grabbing the productcode, and saving to a file which then copies to a remote share i have set up.
On error resume Next
Dim strName, WshShell, oReg, keyname, WshNetwork, ComputerName
Set fso = CreateObject("Scripting.FileSystemObject")
Set WshShell = CreateObject("WScript.Shell")
Set WshNetwork = WScript.CreateObject("WScript.Network")
Const HKEY_LOCAL_MACHINE = &H80000002
Const ForReading = 1, ForWriting = 2, ForAppending = 8
ComputerName = WshNetwork.ComputerName
FileName = ComputerName & "_data.txt"
'FileName = "sep_data.txt"
'=============================================
'Chage the value here with DisplayName's value
strName = "Symantec Endpoint Protection"
'=============================================
'currentDirectory = Left(WScript.ScriptFullName,(Len(WScript.ScriptFullName))-(Len(WScript.ScriptName)))
currentDirectory = "c:\windows\temp\"
'set location in registry we want to get data from
Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & ComputerName & "\root\default:StdRegProv")
strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
oReg.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys
'check each key in uninstall for any display name called Symantec Endpoint Protection
For Each subkey In arrSubKeys
keyname = ""
keyname = wshshell.RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" & subkey & "\DisplayName")
If keyname = strName then
i = subkey
End If
' Writes text to file if it exists
If i Then
'open text file for writing
Set filetxt = fso.OpenTextFile(currentDirectory & FileName, 2, True)
'write to text file
filetxt.WriteLine "" & computerName & "," & i & ""
'Close file
filetxt.Close
'Copy file to network share
fso.CopyFile "c:\windows\temp\" & FileName & "", "\\hostname\test\", true
End If
Next
Set WshShell = Nothing
Set ObjReg = Nothing
Set computerName = Nothing
Set i = Nothing
WScript.Quit
Here you can find why (in short there are separate structures for 32 and 64 bits in the registry and the file system access is redirected)
For a how, if the application/registry is 32 bit, start the script using the 32 bit script host version (in 64b OS versions, the 32b executables are under %systemroot%\SysWOW64)
"%systemroot%\SysWOW64\cscript.exe" myscript.vbs
The inverse problem, you have a 32 bits process but you need to access the 64 bit registry, requires the start of a 64 bit process, and here things change.
While the executables in %systemroot%\System32 are 64 bits, as the current process is 32 bits it is running under a registry and file system redirection and any reference to %systemroot%\System32 in converted to a reference to %systemroot%\SysWOW64 (32bit processes expect a 32bit OS). This can be solved using
"%systemroot%\sysnative\cscript.exe" myscript.vbs
Yes, if you search the sysnative folder from a 64 bit process you will not find it, but from a 32 bit process it gives you access to the 64 bit system32 folder.
edited to include a workaround. The basic idea is to try to find the required information using the current engine. If not found, the script relaunches itself with a different host.
Option Explicit
Const HKEY_LOCAL_MACHINE = &H80000002
Const ForReading = 1 _
, ForWriting = 2 _
, ForAppending = 8
Const UNINSTALL_KEY_PATH = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
Const KEY_DISPLAY_NAME = "Symantec Endpoint Protection"
Const TARGET_FOLDER = "C:\TEMP"
Const ARGUMENT_FLAG = "_CHILD_"
Dim shell
Set shell = WScript.CreateObject("WScript.Shell")
Dim retValue, alternateHost
If Not WScript.Arguments.Named.Exists(ARGUMENT_FLAG) Then
retValue = shell.Run( quote(WScript.FullName) & " " & quote(WScript.ScriptFullName) & " /" & ARGUMENT_FLAG, 0, True )
If retValue > 0 Then
With WScript.CreateObject("Scripting.FileSystemObject")
If .GetFile( WScript.FullName ).ParentFolder.Name = "SysWOW64" Then
alternateHost = "\sysnative\"
Else
alternateHost = "\SysWOW64\"
End If
alternateHost = .BuildPath( shell.ExpandEnvironmentStrings("%systemroot%") & alternateHost, "cscript.exe" )
If .FileExists( alternateHost ) Then
Call shell.Run( quote(alternateHost) & " " & quote(WScript.ScriptFullName) & " /" & ARGUMENT_FLAG, 0, True )
End If
End With
End If
WScript.Quit
End If
Dim reg
Set reg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
Dim subKeys, subKey, value, keyFound
keyFound = False
reg.EnumKey HKEY_LOCAL_MACHINE, UNINSTALL_KEY_PATH, subKeys
For Each subKey In subKeys
reg.GetStringValue HKEY_LOCAL_MACHINE, UNINSTALL_KEY_PATH & "\" & subkey , "DisplayName", value
If Not IsNull( value ) Then
If value = KEY_DISPLAY_NAME Then
keyFound = True
Exit For
End If
End If
Next
Dim computerName, baseName, fileName, exitCode
If keyFound Then
computerName = WScript.CreateObject("WScript.Network").ComputerName
baseName = computerName & "_data.txt"
With WScript.CreateObject("Scripting.FileSystemObject")
fileName = .BuildPath( shell.ExpandEnvironmentStrings("%temp%"), baseName )
.CreateTextFile( fileName, True ).WriteLine( computerName & "," & KEY_DISPLAY_NAME )
.CopyFile fileName, .BuildPath( TARGET_FOLDER, .GetFile( fileName ).Name )
End With
exitCode = 0
Else
exitCode = 1
End If
Call WScript.Quit( exitCode )
Function quote( text )
quote = """" & text & """"
End Function
i used an alternative method to move the file to a share. why the 64 bit os was getting missed was due to my reg query call. it was missing /reg64 at the end.
I have a application that needs multiple configuration files to be written to reg_sz as
"sEndorsement"="C:\\x\\file1.txt
C:\\x\\file2.txt"
Adding this via regedit doesn't works. i tried using a vbscript to do so as below,
Dim myval
myval = "C:\\x\\file1.txt" & VbCrLf _
& "C:\\x\\file2.txt" & VbCrLf _
& "C:\\y\\file3.dll" & VbCrLf
Dim WSHShell
set WSHShell = CreateObject("WScript.Shell")
WSHShell.RegWrite "HKEY_USERS\abc\def\TheSelectedFiles", myval, "REG_SZ"
But it still ended up in coming as single line.. i am not sure.. Is there someone can help me with it?? Thanks
For multiple lines, that's called REG_MULTI_SZ not REG_SZ.
You cannot create keys under the root of HKEY_USERS, you need to use the .Default subkey. The values will appear to be on the same line, but if you double click the value, you can see there are 3 lines.
Set objRegistry = GetObject("winmgmts:{impersonationLevel=impersonate,authenticationLevel=pktPrivacy}!\\.\root\default:StdRegProv")
Const HKEY_CLASSES_ROOT = &H80000000
Const HKEY_CURRENT_USER = &H80000001
Const HKEY_LOCAL_MACHINE = &H80000002
Const HKEY_USERS = &H80000003
Const HKEY_CURRENT_CONFIG = &H80000005
strKeyPath = ".DEFAULT\abc\def\TheSelectedFiles"
MultValueName = "sEndorsement"
iValues = Array("C:\x\file1.txt", "C:\x\file2.txt", "C:\y\file3.dll")
objRegistry.CreateKey HKEY_USERS,strKeyPath
objRegistry.SetMultiStringValue HKEY_USERS,strKeyPath,MultValueName,iValues
I am stumped here. I can't seem to wrap my head around getting the subkeys read into an array, and then walk through each subkey to search for a certain Dword value. I could assign variables to every subkey (which would take forever.)
My script works fine when I have it set up to look at one subkey and one value:
Const HKLM = &H80000002
Const REG_SZ = 1
Const REG_EXPAND_SZ = 2
Const REG_BINARY = 3
Const REG_DWORD = 4
Const REG_MULTI_SZ = 7
strKeyPath = "HKEY_LOCAL_MACHINE\SOFTWARE\Program\Policies\policy1"
strValueName = "lastStatus"
Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")
objRegistry.GetDWORDValue HKLM,strKeyPath,strValueName,dwValue
If dwValue = 0 Then
Wscript.Echo strcomputer & " not done."
Elseif dwvalue = 3 Then
Wscript.Echo strcomputer & " is done!"
But, I need the script to walk through HKLM\Software\program\policies\policy1, then HKLM\Software\program\policies\policy2, then HKLM\Software\program\policies\policy3... until it reads every policy, of which there are 32 to 34 depending on the computer.
Then I need to check within each policy subkey if a dword value = 0 or 3.
I am not sure what you mean by "can't wrap my head around arrays". Do you mean you don't like the idea? In that case if you can be sure about the names of the subkeys you can do it like
For i = 1 To 34
strKeyPath = "SOFTWARE\Program\Policies\policy" & i
objRegistry.GetDWORDValue HKLM,strKeyPath,strValueName,dwValue
Next
If you just mean you don't know the proper way to do it, the normal approach would be
Const HKLM = &H80000002
strComputer = "."
strKeyPath = "SOFTWARE\Policies\"
strValueName = "lastStatus"
Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")
objRegistry.EnumKey HKLM, strKeyPath, subKeys
For Each subKey In subKeys
objRegistry.GetDWORDValue HKLM,strKeyPath & subKey ,strValueName,dwValue
Next
Please note that either way, if you use the WMI registry provider the keyPaths are always without "HKEY_LOCAL_MACHINE\" because you have (correctly) specified that as constant already.
I want to see with vbs, registry path. I have solution for reading the key.
Set wshShell = CreateObject( "WScript.Shell" )
WScript.Echo "ID = " _
& wshShell.RegRead( "HKEY_USERS\key" )
Output is registry key string.
I want script which to show all paths in HKEY_USERS.
For example tree:
HKEY_USERS \
S-1-5-20_Classes
S-1-5-20
S-1-5-21
S-1-5-21-15325-362362362 (I want to output only this path)
You can use the WMI StdRegProv.EnumKey methods to list all subkeys under a specific registry key. For example:
Const HKEY_USERS = &H80000003
strComputer = "."
Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" _
& strComputer & "\root\default:StdRegProv")
strKeyPath = ""
objReg.EnumKey HKEY_USERS, strKeyPath, arrSubKeys
For Each subkey In arrSubKeys
WScript.Echo subkey
Next