Prev: VBScript on Windows 64 Bit?
Next: Desktop Labeling....
From: David on 3 Aug 2010 11:18 Need some help creating a vbs file that will replace a server name with another server name and traverse the entire registry, all KEYS and VALUES. Needs to be non-prompting, silent and easily set with the variables. I found the following but it will take a bunch of modification to make it work and it only changes values, not keys. Can anyone help? If LCase(Right(Wscript.FullName, 11)) = "wscript.exe" Then strPath = Wscript.ScriptFullName strCommand = "%comspec% /k cscript """ & strPath & """" Set objShell = CreateObject("Wscript.Shell") objShell.Run(strCommand), 1, True Wscript.Quit End If ' Duplicate these to account for each abbreviation Const HKCR = &H80000000 Const HKEY_CLASSES_ROOT = &H80000000 Const HKCU = &H80000001 Const HKEY_CURRENT_USER = &H80000001 Const HKLM = &H80000002 Const HKEY_LOCAL_MACHINE = &H80000002 Const HKUSERS = &H80000003 Const HKEY_USERS = &H80000003 Const HKCC = &H80000005 Const HKEY_CURRENT_CONFIG = &H80000005 'Value types Const REG_SZ = 1 Const REG_EXPAND_SZ = 2 Const REG_BINARY = 3 Const REG_DWORD = 4 Const REG_MULTI_SZ = 7 strComputer = "." Set objRegistry=GetObject("winmgmts:\\" & _ strComputer & "\root\default:StdRegProv") strKeyPath = "HKCU\Software" If Right(strKeyPath, 1) = "\" Then strKeyPath = Left(strKeyPath, Len(strKeyPath) - 1) strRoot = UCase(Left(strKeyPath, InStr(strKeyPath, "\") - 1)) strKeyPath = Mid(strKeyPath, InStr(strKeyPath, "\") + 1) arrChanges = Array(_ "kkppqqcdw7--|--shitchanged",_ "TestValue2--|--TestValue2Changed"_ ) For Each strChange In arrChanges strValueToFind = Split(strChange, "--|--")(0) strReplaceWith = Split(strChange, "--|--")(1) Select Case strRoot Case "HKCR", "HKEY_CLASSES_ROOT" strRootKey = HKCR Case "HKCU", "HKEY_CURRENT_USER" strRootKey = HKCU Case "HKLM", "HKEY_LOCAL_MACHINE" strRootKey = HKLM Case "HKUSERS", "HKEY_USERS" strRootKey = HKUSERS Case "HKCC", "HKEY_CURRENT_CONFIG" strRootKey = HKCC Case Else MsgBox "Invalid root key entered." WScript.Quit End Select strFoundAt = "" SearchKeys strRootKey, strKeyPath, strValueToFind, strReplaceWith WScript.Echo "Finished searching subkeys." Next Sub ChangeValue(strRootPath, strPath, strType, strReplacement) Wscript.Echo strValueToFind & " was found at" & VbCrLf & _ strPath & VbCrLf & _ "Value Type: " & strType & VbCrLf strKey = Left(strPath, InStrRev(strPath, "\") - 1) strValue = Mid(strPath, InStrRev(strPath, "\") + 1) Select Case strType Case "String" On Error Resume Next intReturn = objRegistry.SetStringValue(strRootPath, strKey, strValue, strReplacement) Err.Clear On Error GoTo 0 Case "ExpandedString" On Error Resume Next intReturn = objRegistry.SetExpandedStringValue(strRootPath, strKey, strValue, strReplacement) Err.Clear On Error GoTo 0 Case "Binary" On Error Resume Next intReturn = objRegistry.SetBinaryValue(strRootPath, strKey, strValue, strReplacement) Err.Clear On Error GoTo 0 Case "DWord" On Error Resume Next intReturn = objRegistry.SetDWORDValue(strRootPath, strKey, strValue, strReplacement) Err.Clear On Error GoTo 0 Case "MultiString" On Error Resume Next intReturn = objRegistry.SetMultiStringValue(strRootPath, strKey, strValue, Array(strReplacement)) Err.Clear On Error GoTo 0 End Select If intReturn = 0 Then WScript.Echo "Changed from " & strValueToFind & " to " & strReplaceWith & VbCrLf Else WScript.Echo "Failed to change from " & strValueToFind & " to " & strReplaceWith End If End Sub Sub SearchKeys(strRootPath, strPath, strFind, strReplaceWith) 'strFoundAt = "" SearchValues strRootPath, strPath, strFind, strReplaceWith objRegistry.EnumKey strRootPath, strPath, arrSubkeys If TypeName(arrSubkeys) <> "Null" Then For Each objSubkey In arrSubkeys 'WScript.Echo strPath & "\" & objSubKey SearchKeys strRootPath, strPath & "\" & objSubKey, strFind, strReplaceWith Next End If End Sub Sub SearchValues(strRootPath, strPath, strFind, strReplaceWith) strType = "" objRegistry.EnumValues strRootPath, strPath, arrValueNames, arrValueTypes If TypeName(arrValueNames) <> "Null" Then For intVal = LBound(arrValueNames) To UBound(arrValueNames) Select Case arrValueTypes(intVal) Case REG_SZ If VarType(strFind) = vbString Then objRegistry.GetStringValue strRootPath, strPath, arrValueNames(intVal), strValue If strValue = strFind Then strFoundAt = strPath & "\" & arrValueNames(intVal) strType = "String" End If End If Case REG_EXPAND_SZ If VarType(strFind) = vbString Then objRegistry.GetExpandedStringValue strRootPath, strPath, arrValueNames(intVal), strValue If strValue = strFind Then strFoundAt = strPath & "\" & arrValueNames(intVal) strType = "ExpandedString" End If End If Case REG_BINARY If VarType(strFind) = vbByte Then objRegistry.GetBinaryValue strRootPath, strPath, arrValueNames(intVal), strValue If strValue = strFind Then strFoundAt = strPath & "\" & arrValueNames(intVal) strType = "Binary" End If End If Case REG_DWORD If VarType(strFind) = vbString Then objRegistry.GetDWordValue strRootPath, strPath, arrValueNames(intVal), strValue If strValue = strFind Then strFoundAt = strPath & "\" & arrValueNames(intVal) strType = "DWord" End If End If Case REG_MULTI_SZ If VarType(strFind) = vbString Then objRegistry.GetMultiStringValue strRootPath, strPath, arrValueNames(intVal), arrValues For Each strValue In arrValues If strValue = strFind Then strFoundAt = strPath & "\" & arrValueNames(intVal) strType = "MultiString" End If Next End If End Select If strFoundAt <> "" Then ChangeValue strRootPath, strFoundAt, strType, strReplaceWith strFoundAt = "" End If Next End If End Sub
From: Al Dunbar on 3 Aug 2010 21:07 So, you want us to review a 200 line script from who knows where and adapt it so it does something useful for you? Good luck on that one. That said I'll try to make a few small contributions... "David" <David(a)nospam.goodwinpictures.com> wrote in message news:uu12s8xMLHA.5776(a)TK2MSFTNGP06.phx.gbl... > Need some help creating a vbs file that will replace a server name with > another server name and traverse the entire registry, all KEYS and VALUES. > Needs to be non-prompting, silent and easily set with the variables. I > found the following but it will take a bunch of modification to make it > work and it only changes values, not keys. Can anyone help? > > If LCase(Right(Wscript.FullName, 11)) = "wscript.exe" Then > strPath = Wscript.ScriptFullName > strCommand = "%comspec% /k cscript """ & strPath & """" > Set objShell = CreateObject("Wscript.Shell") > objShell.Run(strCommand), 1, True > Wscript.Quit > End If > > ' Duplicate these to account for each abbreviation > Const HKCR = &H80000000 > REM Const HKEY_CLASSES_ROOT = &H80000000 > Const HKCU = &H80000001 > REM Const HKEY_CURRENT_USER = &H80000001 > Const HKLM = &H80000002 > REM Const HKEY_LOCAL_MACHINE = &H80000002 > Const HKUSERS = &H80000003 > REM Const HKEY_USERS = &H80000003 > Const HKCC = &H80000005 > REM Const HKEY_CURRENT_CONFIG = &H80000005 1. I comment half of the above statements, as your script never references these constants by the long names you have assigned them. HKEY_CLASSES_ROOT does appear in the text, but only as a quoted string. > > 'Value types > Const REG_SZ = 1 > Const REG_EXPAND_SZ = 2 > Const REG_BINARY = 3 > Const REG_DWORD = 4 > Const REG_MULTI_SZ = 7 > > strComputer = "." > > Set objRegistry=GetObject("winmgmts:\\" & _ > strComputer & "\root\default:StdRegProv") > > strKeyPath = "HKCU\Software" > If Right(strKeyPath, 1) = "\" Then strKeyPath = Left(strKeyPath, > Len(strKeyPath) - 1) > strRoot = UCase(Left(strKeyPath, InStr(strKeyPath, "\") - 1)) > strKeyPath = Mid(strKeyPath, InStr(strKeyPath, "\") + 1) 2. The net effect of the above four statements is identical to that of these two statements: strRoot = "HKCU" strKeyPath = "Software" > > arrChanges = Array(_ > "kkppqqcdw7--|--shitchanged",_ > "TestValue2--|--TestValue2Changed"_ > ) > > > For Each strChange In arrChanges > strValueToFind = Split(strChange, "--|--")(0) > > strReplaceWith = Split(strChange, "--|--")(1) > > Select Case strRoot > Case "HKCR", "HKEY_CLASSES_ROOT" > strRootKey = HKCR > Case "HKCU", "HKEY_CURRENT_USER" > strRootKey = HKCU > Case "HKLM", "HKEY_LOCAL_MACHINE" > strRootKey = HKLM > Case "HKUSERS", "HKEY_USERS" > strRootKey = HKUSERS > Case "HKCC", "HKEY_CURRENT_CONFIG" > strRootKey = HKCC > Case Else > MsgBox "Invalid root key entered." > WScript.Quit > End Select 3. Because strRoot is only ever assigned the value "HKCU", the above select case structure can be replaced by this single statement: strRootKey = HKCU > > strFoundAt = "" > > SearchKeys strRootKey, strKeyPath, strValueToFind, strReplaceWith > > WScript.Echo "Finished searching subkeys." > > Next 4. At this point I'll turn you over to anyone who actually has the time to read through this poorly written script to see what sense, if any, it might make. You say you found this - where, precisely, or, more appropriately, under what log? It is missing at least a couple of critical aspects that might have made this less of a wild goose chase, namely, some indenting and more judicious use of whitespace, along with some comments. Perhaps this script is capable of making changes to registry values somewhat along the lines of what you are trying to do. But just to adapt this code to do that would be a significant task. As to changing (i.e. renaming) registry keys, you seem to be asking for trouble. Suppose the registry contains keys named "homer" and "marge", and the server names in question happen to be "homer" (to find) and "marge" (to replace with). As long as a key called "marge" exists, the key called "homer" in the same parent key will not be able to be changed to "marge". I suspect that if you ever get this script working to the point where it modifies the registry, that running it will disable the computer. Good luck with that. /Al > Sub ChangeValue(strRootPath, strPath, strType, strReplacement) > Wscript.Echo strValueToFind & " was found at" & VbCrLf & _ > strPath & VbCrLf & _ > "Value Type: " & strType & VbCrLf > strKey = Left(strPath, InStrRev(strPath, "\") - 1) > strValue = Mid(strPath, InStrRev(strPath, "\") + 1) > Select Case strType > Case "String" > On Error Resume Next > intReturn = objRegistry.SetStringValue(strRootPath, strKey, strValue, > strReplacement) > Err.Clear > On Error GoTo 0 > Case "ExpandedString" > On Error Resume Next > intReturn = objRegistry.SetExpandedStringValue(strRootPath, strKey, > strValue, strReplacement) > Err.Clear > On Error GoTo 0 > Case "Binary" > On Error Resume Next > intReturn = objRegistry.SetBinaryValue(strRootPath, strKey, strValue, > strReplacement) > Err.Clear > On Error GoTo 0 > Case "DWord" > On Error Resume Next > intReturn = objRegistry.SetDWORDValue(strRootPath, strKey, strValue, > strReplacement) > Err.Clear > On Error GoTo 0 > Case "MultiString" > On Error Resume Next > intReturn = objRegistry.SetMultiStringValue(strRootPath, strKey, strValue, > Array(strReplacement)) > Err.Clear > On Error GoTo 0 > End Select > If intReturn = 0 Then > WScript.Echo "Changed from " & strValueToFind & " to " & strReplaceWith & > VbCrLf > Else > WScript.Echo "Failed to change from " & strValueToFind & " to " & > strReplaceWith > End If > End Sub > > Sub SearchKeys(strRootPath, strPath, strFind, strReplaceWith) > 'strFoundAt = "" > SearchValues strRootPath, strPath, strFind, strReplaceWith > objRegistry.EnumKey strRootPath, strPath, arrSubkeys > If TypeName(arrSubkeys) <> "Null" Then > For Each objSubkey In arrSubkeys > 'WScript.Echo strPath & "\" & objSubKey > SearchKeys strRootPath, strPath & "\" & objSubKey, strFind, strReplaceWith > Next > End If > End Sub > > Sub SearchValues(strRootPath, strPath, strFind, strReplaceWith) > strType = "" > objRegistry.EnumValues strRootPath, strPath, arrValueNames, arrValueTypes > If TypeName(arrValueNames) <> "Null" Then > For intVal = LBound(arrValueNames) To UBound(arrValueNames) > Select Case arrValueTypes(intVal) > Case REG_SZ > If VarType(strFind) = vbString Then > objRegistry.GetStringValue strRootPath, strPath, arrValueNames(intVal), > strValue > If strValue = strFind Then > strFoundAt = strPath & "\" & arrValueNames(intVal) > strType = "String" > End If > End If > Case REG_EXPAND_SZ > If VarType(strFind) = vbString Then > objRegistry.GetExpandedStringValue strRootPath, strPath, > arrValueNames(intVal), strValue > If strValue = strFind Then > strFoundAt = strPath & "\" & arrValueNames(intVal) > strType = "ExpandedString" > End If > End If > Case REG_BINARY > If VarType(strFind) = vbByte Then > objRegistry.GetBinaryValue strRootPath, strPath, arrValueNames(intVal), > strValue > If strValue = strFind Then > strFoundAt = strPath & "\" & arrValueNames(intVal) > strType = "Binary" > End If > End If > Case REG_DWORD > If VarType(strFind) = vbString Then > objRegistry.GetDWordValue strRootPath, strPath, arrValueNames(intVal), > strValue > If strValue = strFind Then > strFoundAt = strPath & "\" & arrValueNames(intVal) > strType = "DWord" > End If > End If > Case REG_MULTI_SZ > If VarType(strFind) = vbString Then > objRegistry.GetMultiStringValue strRootPath, strPath, > arrValueNames(intVal), arrValues > For Each strValue In arrValues > If strValue = strFind Then > strFoundAt = strPath & "\" & arrValueNames(intVal) > strType = "MultiString" > End If > Next > End If > End Select > If strFoundAt <> "" Then > ChangeValue strRootPath, strFoundAt, strType, strReplaceWith > strFoundAt = "" > End If > Next > End If > End Sub > >
From: Stefan Kanthak on 4 Aug 2010 10:23 "Al Dunbar" <alandrub(a)hotmail.com> wrote: > So, you want us to review a 200 line script from who knows where and adapt > it so it does something useful for you? Good luck on that one. That said > I'll try to make a few small contributions... > > "David" <David(a)nospam.goodwinpictures.com> wrote in message > news:uu12s8xMLHA.5776(a)TK2MSFTNGP06.phx.gbl... I dont see postings from people who cant write their full name... [...] > I suspect that if you ever get this script working to the point where it > modifies the registry, that running it will disable the computer. Good luck > with that. Besides that: (recursive) enumeration of registry keys via WMI's VBScript interface doesn't work on NT 5.x, since the RegQueryInfoKey() function of the Win32-API which is internally used returns incorrect maximum keylength, typically for some keys below the inactive [HKLM\System\ControlSet###]. Stefan
From: David Goodwin on 4 Aug 2010 14:04 Let me explain a little better. I need to replace a server value on 350+ workstations, the key container will be named this value and some of the keys under it will be as well. The script from Bill at http://www.billsway.com/vbspage/ under 'Registry Search Tool' will find the value I specify for and give it to me in a nice text file. Problem is that I need to make the modification to change it to another server value and apply the changes back. This all needs to be done silently as our end users do not need to see this change. It would be nice to read the entire registry, store the value in an array, change the array and then write back to the registry. This will only be done on XP Pro SP2.
From: Todd Vargo on 4 Aug 2010 18:51
Al Dunbar wrote: > So, you want us to review a 200 line script from who knows where and adapt > it so it does something useful for you? Good luck on that one. That said > I'll try to make a few small contributions... > .... > > 4. At this point I'll turn you over to anyone who actually has the time to > read through this poorly written script to see what sense, if any, it > might make. You say you found this - where, precisely, or, more > appropriately, under what log? It is missing at least a couple of critical > aspects that might have made this less of a wild goose chase, namely, some > indenting and more judicious use of whitespace, along with some comments. > > Perhaps this script is capable of making changes to registry values > somewhat along the lines of what you are trying to do. But just to adapt > this code to do that would be a significant task. > > As to changing (i.e. renaming) registry keys, you seem to be asking for > trouble. Suppose the registry contains keys named "homer" and "marge", and > the server names in question happen to be "homer" (to find) and "marge" > (to replace with). As long as a key called "marge" exists, the key called > "homer" in the same parent key will not be able to be changed to "marge". > > I suspect that if you ever get this script working to the point where it > modifies the registry, that running it will disable the computer. Good > luck with that. FWIW, the code is indented, but for some reason, Microsoft newsreaders eliminate tab characters instead of converting them to white space. That is why I prefer spaces for indenting. I agree with your other comments. ISTM, the OP could use regedit to export the key in question to a reg file, modify it (including a delete original key line) and then import the modified reg file. Unfortunately, the code lacked enough information to offer assistance. -- Todd Vargo (Post questions to group only. Remove "z" to email personal messages) |