1
votes

I have a question based on a previus question asked here.

I need to change registry key entries on multiple computers where REG GUIDs of said registry keys are different on every machine. I have found that I can pull the regkey into a .reg or .txt file, find the “Device_State” values, and replace them with what I want using a .vbs script similar to the one in the link I referenced above.

I cannot use any 3rd party solutions for this. It must be organic to Windows, by nature (Windows 7 and windows 10 is currently my env).

Problem

My Test.vbs script appears to work when I just have the .reg file in a directory, and run (double-click) the .vbs script (from same directory).

The script finds and replaces the strings I want and writes it all back to the .reg file (in this case, "replace.reg"). However, when I call it from my batch file, the .vbs script returns an error:

Line: 15 Char: 1 Error: Invalid procedure call or argument
Code: 800A0005 Source: Microsoft VBScrpt runtime error

line 15, 1 in my code is: objFile.Write strNewText.

When I check the .reg to see what has changed, the file is now blank. It seems like the script is reading the content of the file into the strText variable, finding my values, replacing values, then erroring out and not writing back to the .reg file.

Batch file

My batch file does the following:

  1. creates a directory for backup and to work out of

    md c:\windows\patches
    reg export "hkey_name" C:\windows\patches\backup\backup.reg
    
  2. exports the registry key to a .reg file (and a separate .txt for reference) for actual manipulation of file content:

    reg export “hkey_name” c:\windows\patches\replace.reg
    reg export "hkey_name" c:\windows\patches\replace.txt
    
  3. calls the .vbs script

    @call cscript “%~dp0Test.vbs”
    

    I have also tried

    runas /user:localadmin /savecred "wscript.exe c:\windows\Patches\Test.vbs"
    
  4. imports the new .reg into the registry (this is the plan; have not gotten this far yet).

    reg import c:\windows\patches\replace.reg
    

VBScript

The Test.vbs script is as follows:

Option Explicit
Dim objFSO, objFile, strText, strNewText
Const ForReading = 1
Const ForWriting = 2

Set objFSO = CreateObject(“Scripting.FileSystemObject”)
Set objFile = objFSO.OpentTextFile(“C:\Windows\Patches\backup.reg”, ForReading)

strText = objFile.ReadAll
objFile.Close
strNewText = Replace(strText, ”HKEY”, ”BLAH-BLAH”)      '<—– this is just for testing function!
strNewText = Replace(strText, "LOCAL", "EAT_SOME_FOOD") '<—-just for testing function!

Set objFile = objFSO.OpenTextFile("C:\Windows\Patches\backup.reg", ForWriting)
objFile.Write strNewText
objFile.Close

MsgBox "Done"

So, again, to reiterate, the VBScript does exactly what I want when I run it independently. But when I call it from a batch file, it "wipes out" (or fails to write to) the file I need changed.

I am running this as an administrator of the local system, with full rights to the files in question.

I am running this from an elevated CMD prompt/window.

Question

Does anyone know why this would work independently of the batch file, yet not work when called by the batch file? I'm thinking it has to have something to do with permissions or authority to open/close the file for reading/writing while "inside" a batch routine. I just don't know enough to figure it out.

***************************** UPDATE ************************************

I have narrowed this down even further and here is what I'm finding: -
1) I run my batch file that creates a backup of the registry keys I need to edit. The batch file creates a .reg file and a .txt file of the same registry keys (this is just for my own security to have both). I'm also granting full rights to everyone, users, administrators on this folder/files

2) I then run the find/replace text vbScript. It errors out on the line "objFile.Write strNewText". When it errors out it appears to wipe out the contents of the .reg file.

3) I found that if I take everything in the .txt file (same exact text) and paste into the .reg file (AFTER the vbscript errors out) and THEN run my script, it works.

I have tried manually deleting the .reg contents and replacing it with the .txt content and trying to run the script, and it errors out the same way and again appears to wipe out the contents of the .reg file. It's ONLY AFTER THE VBSCRIPT errors out on writing to the file, appears to wipe out the contents, that I can paste the contents of the .txt file into the .reg file and run the VBScript ... and it works. I'm so confused by this. I can't imagine what's going on. Please, I'm hoping someone else can help me. Thanks.

1
not related to your problem. But are you aware that your line 12) overwrites the result fo line 11) ?Stephan
Yes. The idea is that it searches for a value (dword:00000001) and replaces it with (dword:00000000). The next line in my actual script finds yet another value (dword:10000004) and replaces it with (dword:00000000) That last thing it will do is find all dword:00000000 and replace with dword 10000001 It's the only way I could think of to simply find all the different possible states of that 'dword' that we have, and replace with the state I wanted.BigDaddyB
Line 16 as you had previously numbered it was objFile.Close not objFile.Write strNewText.Compo
The script errors out on objFile.Write strNewTextBigDaddyB
Do you have the typographical quotation marks “” also in your script or only here in your post? note that you must use normal ones "" in the code!aschipfl

1 Answers

1
votes

There is likely an error being thrown that you can't see. In your batch file, at the end of each line, add > output.txt, like so:

md c:\windows\patches
reg export "hkey_name" C:\windows\patches\backup\backup.reg > outputExport1.txt
reg export "hkey_name" c:\windows\patches\replace.reg > outputExport2.txt
reg export "hkey_name" c:\windows\patches\replace.txt > outputExport3.txt
cscript "%~dp0Test.vbs" > outputVBS.txt

This will dump any error information you would have seen in the command prompt to the output file. Alternatively, you can manually run each line of your batch file in a command prompt and see what it says there.

Inside your script, you can add additional debugging outputs (and they will also either be dumped into your output file or display in the command prompt if you run it manually):

Option Explicit
Dim objFSO, objFile, strText, strNewText
Const ForReading = 1
Const ForWriting = 2

WScript.Echo "Reading the file"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpentTextFile("C:\Windows\Patches\backup.reg", ForReading)

strText = objFile.ReadAll
WScript.Echo "File Contents: " & strText
objFile.Close
strNewText = Replace(strText, "HKEY", "BLAH-BLAH")      '<—– this is just for testing function!
WScript.Echo "Did first replace: " & strNewText 
strNewText = Replace(strNewText, "LOCAL", "EAT_SOME_FOOD") '<—-just for testing function!
WScript.Echo "Did second replace: " & strNewText      


Set objFile = objFSO.OpenTextFile("C:\Windows\Patches\backup.reg", ForWriting)
WScript.Echo "Opened the File for Writing"
objFile.Write strNewText
WScript.Echo "Wrote the File"
objFile.Close
WScript.Echo "Closed the File"    
WScript.Echo "Done"

Note that in the code above I corrected a bug you have in the second Replace - in the original code you are reusing the strText variable, which means the changes done by the first Replace are overwritten.