how to read all the values of a registry key with vbscript? - vbscript

I have the following values in my registry
key:
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Accepted Documents\
values:
* -> application/msword
** -> application/vnd.ms-excel
*** -> application/vnd.ms-powerpoint
and so on
I'd like to know how to read all of them
with Wscript.Shell, RegRead I can only read one value, but I don't know the values in advance...

Well, I got it
I had to use wmi, like this:
option explicit
const HKLM = &H80000002
dim keyPath
keyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Accepted Documents"
dim reg
dim valueNames, types
dim value
dim i
set reg = getObject( "Winmgmts:root\default:StdRegProv" )
if reg.enumValues( HKLM, keyPath, valueNames, types ) = 0 then
if isArray( valueNames ) then
for i = 0 to UBound( valueNames )
reg.getStringValue HKLM, keyPath, valueNames(i), value
msgBox( valueNames(i) & "=" & value )
next
end if
end if
saludos
sas

Related

Creating a Registry text file with vbs

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

Add Value to 3 Registry locations

I am trying to add a value to 3 locations in the registry:
HKEY_CURRENT_USER\Software\Intel\Indeo
HKEY_LOCAL_MACHINE\SOFTWARE\Intel\Indeo
HKEY_USERS\S-1-5-21-669792009-2657969199-152103076-1000\Software\Intel\Indeo
This is the string I need to add to each registry path:
"Options"="360611321911"
For some reason I am unable to test this code just to see if it adds the value:
CreateObject("WScript.Shell").RegWrite "HKEY_USERS\S-1-5-21-669792009-2657969199-152103076-1000\Software\Intel\Indeo", "C:\Program Files\FastTuner\Clean.exe"
You can add these two functions to your project to work with values in the Registry:
' Write Reg:
' Write to the Windows Registry
' RegType should be 'REG_SZ' for string, 'REG_DWORD' for an integer,
' 'REG_BINARY' for a binary or boolean, and 'REG_EXPAND_SZ' for an expandable string
Function WriteReg(RegPath, Value, RegType)
Dim Key
Dim objRegistry
Set objRegistry = CreateObject("Wscript.shell")
Key = objRegistry.RegWrite(RegPath, Value, RegType)
WriteReg = Key
End Function
' Read Reg:
' Read from the Windows Registry
Function ReadReg(RegPath)
Dim Key
Dim objRegistry
Set objRegistry = CreateObject("Wscript.shell")
Key = objRegistry.RegRead(RegPath)
ReadReg = Key
End Function

How to iterate registry from the root?

I would like to search all the registry (HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS and all of the subkeys) for a specific value and if there is a match I would like to delete this entry. Is there a way to do this? I found a sample like below but it is not iterating all the registry.
Best Regards and thanks in advance.
Const HKCU = &H80000001
Const HKLM = &H80000002
Const HKU = &H80000003
Const REG_SZ = 1
Const REG_EXPAND_SZ = 2
Const REG_BINARY = 3
Const REG_DWORD = 4
Const REG_MULTI_SZ = 7
valueToDelete = "Alex De Souza"
Set reg = GetObject("winmgmts://./root/default:StdRegProv")
Sub DeleteFromRegistry(hive, key, searchValue)
'enumerate values and delete matching ones
rc = reg.EnumValues(hive, key, values, types)
If Not IsNull(values) Then
For i = LBound(values) To UBound(values)
strValueName = values(i)
Select Case types(i)
' Show a REG_SZ value
'
Case REG_SZ
reg.GetStringValue hive, key, strValueName, strValue
If InStr(strValue, searchValue) > 0 Then
wscript.echo "Found " & key & ": "& strValueName & " (REG_SZ) = " & strValue
rc = reg.DeleteValue(hive, key, strValue)
End If
' Show a REG_EXPAND_SZ value
'
Case REG_EXPAND_SZ
reg.GetExpandedStringValue hive, key, strValueName, strValue
If InStr(strValue, searchValue) > 0 Then
wscript.echo "Found "& key & ": " & strValueName & " REG_EXPAND_SZ) = " & strValue
rc = reg.DeleteValue(hive, key, strValue)
End If
' Show a REG_DWORD value
'
Case REG_DWORD
reg.GetDWORDValue hive, key, strValueName, uValue
If InStr(strValue, searchValue) > 0 Then
wscript.echo "Found "& key & ": " & strValueName & " (REG_DWORD) = " & strValue
rc = reg.DeleteValue(hive, key, strValue)
End If
End Select
Next
End If
'enumerate subkeys and recurse
rc = reg.EnumKey(hive, key, subkeys)
If Not IsNull(subkeys) Then
For Each sk In subkeys
If key = "" Then
path = sk
Else
path = key & "\" & sk
End If
DeleteFromRegistry hive, path, searchValue
Next
End If
End Sub
'iterate over hives (HKCR can be ignored, because it's just a combining view
'on 2 subkeys of HKLM and HKCU)
For Each hive In Array(HKCU, HKLM, HKU)
DeleteFromRegistry hive, "", valueToDelete
Next
You need a recursive procedure for this.
Const HKCU = &H80000001
Const HKLM = &H80000002
Const HKU = &H80000003
valueToDelete = "..."
Set reg = GetObject("winmgmts://./root/default:StdRegProv")
Sub DeleteFromRegistry(hive, key, searchValue)
'enumerate values and delete matching ones
rc = reg.EnumValues(hive, key, values, types)
If Not IsNull(values) Then
For Each val In values
If val = searchValue Then rc = reg.DeleteValue(hive, key, val)
Next
End If
'enumerate subkeys and recurse
rc = reg.EnumKey(hive, key, subkeys)
If Not IsNull(subkeys) Then
For Each sk In subkeys
If key = "" Then
path = sk
Else
path = key & "\" & sk
End If
DeleteFromRegistry hive, path, valueToDelete
Next
End If
End Sub
'iterate over hives (HKCR can be ignored, because it's just a combining view
'on 2 subkeys of HKLM and HKCU)
For Each hive In Array(HKCU, HKLM, HKU)
DeleteFromRegistry hive, "", valueToDelete
Next

search registry for value if match found delete parent key

I need help with a script that would traverse through the registry for a particular value and once match is found delete the parent key. I have found a code but it does not work. I suspect that is in not traversing through the registry key for match.
Option Explicit
Const HKEY_LOCAL_MACHINE = &H80000002
Const cRegKeyStartingPath = "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
Const cRegValueToFind = "Ossec HIDS"
Const cRegDataToMatch = "DisplayName"
Dim oReg, subkey, arrSubKeys, sCurrentKey, sCurrentValuePath, iDeletedCount
iDeletedCount = 0
Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
oReg.EnumKey HKEY_LOCAL_MACHINE, cRegKeyStartingPath, arrSubKeys
On Error Resume Next
For Each subkey In arrSubKeys
If Err.Number = 0 Then 'in case the collection is empty
sCurrentKey = "HKLM\" & cRegKeyStartingPath & subkey
sCurrentValuePath = sCurrentKey & "\" & cRegValueToFind
If customRegRead(sCurrentValuePath) = cRegDataToMatch Then
WScript.Echo "Going to delete "&sCurrentKey
DeleteRegKey sCurrentKey&"\"
iDeletedCount = iDeletedCount + 1
End If
Else
iDeletedCount = -1
End If
Next
Select Case iDeletedCount
Case 0
WScript.Echo "No matching keys found"
Case -1
WScript.Echo "No subkeys found below HKLM\"&cRegKeyStartingPath
Case Else
WScript.Echo "Deleted " & iDeletedCount & " keys"
End Select
Function customRegRead(sRegValue)
Dim oShell
Dim sRegReturn
Set oShell = CreateObject("WScript.Shell")
On Error Resume Next
Err.Clear
sRegReturn = oShell.RegRead(sRegValue)
If Err.Number<>0 Then
customRegRead = "Failed To Read Value"
Else
customRegRead = sRegReturn
End If
End Function
Sub DeleteRegKey(sKey)
Dim oShell
Set oShell = CreateObject("Wscript.Shell")
oShell.RegDelete sKey
End Sub
If there is something cleaner/better please advise.
I'd suggest to remove all occurrences of On Error Resume Next and stick with WMI methods. Also your current code doesn't use recursion, so you can only find values in immediate subkeys of cRegKeyStartingPath. You'll need recursion for traversing a tree of arbitrary depth.
Use EnumValues to enumerate the values of a given key:
rc = reg.EnumValues(HKLM, key, names, types)
The method returns 0 on success, so you can check for errors by evaluating the return code. After the call finishes the variable names contains an array with the names of the values in key, or Null if the key did not contain any values (short of the default value, that is). So the code for checking if a particular value exists in a given key might look like this:
reg.EnumValues HKLM, key, names, types
If Not IsNull(names) Then
For Each name In names
If name = "foo" Then
reg.GetStringValue HKLM, key, name, data
If data = "bar" Then
'delete key here
Exit For
End If
End If
Next
End If
You can traverse the registry by enumerating the subkeys of a given key via EnumKey and recursing into those subkeys:
Sub TraverseRegistry(root, key)
reg.EnumKey root, key, subkeys
If Not IsNull(subkeys) Then
For Each sk In subkeys
TraverseRegistry root, key & "\" & sk
Next
End If
End Sub
To delete a key use the DeleteKey method. The information which key must be deleted is something you already have: it's the value of the variable key from the value enumeration routine when found is true. However, you can't delete a key that has subkeys, so you must delete those first. Something for which you can re-use the traversal routine from above:
Sub DelKey(root, key)
reg.EnumKey root, key, subkeys
If Not IsNull(subkeys) Then
For Each sk In subkeys
DelKey root, key & "\" & sk 'delete subkeys first
Next
End If
'at this point all subkeys have already been deleted, so we can
'now delete the parent key
reg.DeleteKey root, key
End Sub
Put everything together and you get something like this:
Const HKLM = &h80000002
Const StartKey = "SOFTWARE\Wow...ion\Uninstall"
Const SearchValue = "DisplayName"
Const MatchData = "Ossec HIDS"
Set reg = GetObject("winmgmts://./root/default:StdRegProv")
FindAndDeleteKey HKLM, StartKey, SearchValue, MatchData
Sub FindAndDeleteKey(root, key, value, data)
reg.EnumValues HKLM, key, names, types
If Not IsNull(names) Then
For Each name In names
If name = value Then
reg.GetStringValue HKLM, key, name, regdata
If regdata = data Then
DelKey root, key
Exit Sub
End If
End If
Next
End If
'value not found in current key => continue search in subkeys
reg.EnumKey root, key, subkeys
If Not IsNull(subkeys) Then
For Each sk In subkeys
FindAndDeleteKey root, key & "\" & sk, value, data
Next
End If
End Sub
Sub DelKey(root, key)
reg.EnumKey root, key, subkeys
If Not IsNull(subkeys) Then
For Each sk In subkeys
DelKey root, key & "\" & sk 'delete subkeys first
Next
End If
'at this point all subkeys have already been deleted, so we can
'now delete the parent key
reg.DeleteKey root, key
End Sub
Since you're looking for a particular value with particular data you could even simplify FindAndDeleteKey() to this:
Sub FindAndDeleteKey(key)
'Try to read the value directly. If the value doesn't exist this will
'simply return a non-zero return code and set data to Null.
reg.GetStringValue HKLM, key, SearchValue, data
If Not IsNull(data) Then
'value does exist
If data = MatchData Then
DelKey HKLM, key
Exit Sub
End If
End If
'value not found in current key => continue search in subkeys
reg.EnumKey HKLM, key, subkeys
If Not IsNull(subkeys) Then
For Each sk In subkeys
FindAndDeleteKey key & "\" & sk
Next
End If
End Sub
Edit: Below is a version that generates some debug output. Run it in a command prompt via cscript debug_sample.vbs. Note that since you want to delete stuff in HKLM you must run the script "as Administrator" when UAC is enabled.
Const HKLM = &h80000002
Const StartKey = "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
Const SearchValue = "DisplayName"
Const MatchData = "Ossec HIDS"
Set reg = GetObject("winmgmts://./root/default:StdRegProv")
FindAndDeleteKey StartKey
Sub FindAndDeleteKey(key)
WScript.Echo "[HKLM\" & key & "]"
rc = reg.GetStringValue(HKLM, key, SearchValue, data)
If Not IsNull(data) Then
WScript.Echo """" & SearchValue & """=""" & data & """"
If data = MatchData Then
DelKey HKLM, key
Exit Sub
End If
Else
WScript.Echo "'" & SearchValue & "' not found in [HKLM\" & key & "], rc=" & rc
End If
reg.EnumKey HKLM, key, subkeys
If Not IsNull(subkeys) Then
For Each sk In subkeys
FindAndDeleteKey key & "\" & sk
Next
End If
End Sub
Sub DelKey(root, key)
reg.EnumKey root, key, subkeys
If Not IsNull(subkeys) Then
For Each sk In subkeys
DelKey root, key & "\" & sk
Next
End If
rc = reg.DeleteKey(root, key)
WScript.Echo "Deleting [HKLM\" & key & "], rc=" & rc
End Sub
I was able to reproduce a return code 6 (handle is invalid) with an invalid hDefKey value, e.g. &h8000002 (only 7 digits) or h80000002 (missing ampersand).

Why wont this WMI script read my registry string value?

I'm using the examples from technet to try to read a dword / string from HKLM\Microsoft\Windows\CurrentVersion\Run called MyStartupExe.. It is returning empty.. This regular example works:
Const HKEY_CURRENT_USER = &H80000001
strComputer = "."
Set oReg=GetObject( _
"winmgmts:{impersonationLevel=impersonate}!\\" &_
strComputer & "\root\default:StdRegProv")
strKeyPath = "Console"
strValueName = "HistoryBufferSize"
oReg.GetDWORDValue _
HKEY_CURRENT_USER,strKeyPath,strValueName,dwValue
WScript.Echo "Current History Buffer Size: " & dwValue
My adaptation of it does not work. The string and dword value exists in the registry at the key path I'm looking for.
const HKEY_LOCAL_MACHINE = &H80000002
strComputer = "."
Set oReg=GetObject( _
"winmgmts:{impersonationLevel=impersonate}!\\" &_
strComputer & "\root\default:StdRegProv")
strKeyPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"
strValueName = "MyStartUpExe"
oReg.GetDWORDValue _
HKEY_LOCAL_MACHINE,strKeyPath,strValueName,dwValue
WScript.Echo "MyStartupExe" & dwValue
"MyStartUpExe" is most likely a REG_SZ value, not a REG_DWORD value, so you'll have to use GetStringValue() instead of GetDWORDValue().
oReg.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, value
WScript.Echo "MyStartUpExe" & value
Refer to the WMI StdRegProv class.
Or you could just use Shell.RegRead to read registry values where you don't know the values' datatype. If the return code of RegRead is 0 (success) a reg value exists, else if the return code will be some general error code, e.g. &h800xxxxx etc. then no reg value exists. To check your OS architecture type, query the Win32_Processor.Architecture value (where '0' = 'x86' or '9' = 'x64').

Resources