VBScript not working on a 32-bit machine
Hello,
I have a VBScript that eumerates registry keys to find uninstall section and uninstall an msi. But, this does not seem to work on a 32-bit machine. (I have tried running it as user and also system (SCCM). The script fails to detect any installed programs under software\microsoft\windows\currentversion\uninstall on a 32-bit machine. I suspect this would do the same on a 64-bit machine and not look in WOw6432Node registry. Can you please help?
I have a VBScript that eumerates registry keys to find uninstall section and uninstall an msi. But, this does not seem to work on a 32-bit machine. (I have tried running it as user and also system (SCCM). The script fails to detect any installed programs under software\microsoft\windows\currentversion\uninstall on a 32-bit machine. I suspect this would do the same on a 64-bit machine and not look in WOw6432Node registry. Can you please help?
On Error Resume Next
set fs = CreateObject("Scripting.FileSystemObject")
Set Sh = WScript.CreateObject("WScript.Shell")
QUOTE = chr(34)
myret = FINDUNINSTALL("Application Name")
Function FINDUNINSTALL(strsoft)
const HKEY_LOCAL_MACHINE = &H80000002
strComputer = "."
Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
strKeyPath = "software\wow6432node\microsoft\windows\currentversion\uninstall"
oReg.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys
For Each subkey In arrSubKeys
On Error Resume Next
sDisplayName = ""
sDisplayName = Sh.Regread("HKLM\" & strKeyPath & "\" & subkey & "\Displayname")
If instr(lcase(sDisplayName), lcase(strsoft)) > 0 then
sUninstallString = Sh.Regread("HKLM\" & strKeyPath & "\" & subkey & "\uninstallstring")
If instr(lcase(sUninstallString), lcase("msiexec")) > 0 Then
myret = sh.run("cmd.exe /c msiexec /X " & subkey & " /qn REBOOT=ReallySuppress /l*v " & quote & UNLOG & quote,1,True)
End If
End if
Next
strKeyPath = "software\microsoft\windows\currentversion\uninstall" '# Root level
oReg.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys
For Each subkey In arrSubKeys
On Error Resume Next
sDisplayName = ""
sDisplayName = Sh.Regread("HKLM\" & strKeyPath & "\" & subkey & "\Displayname")
If instr(lcase(sDisplayName), lcase(strsoft)) > 0 then
sUninstallString = Sh.Regread("HKLM\" & strKeyPath & "\" & subkey & "\uninstallstring")
If instr(lcase(sUninstallString), lcase("msiexec")) > 0 Then
myret = sh.run("cmd.exe /c msiexec /X " & subkey & " /qn REBOOT=ReallySuppress /l*v " & quote & UNLOG & quote,1,True)
End If
End if
Next
End Function
0 Comments
[ + ] Show comments
Answers (2)
Please log in to answer
Posted by:
anonymous_9363
7 years ago
Crikey! What a confusion of objects and methods you have there!
Rather than the .RegRead of the Shell object, for consistency you should be using the .GetStringValue method of the StRegProv provider. Details can be found here.
If you're going to be doing much registry scripting, you'll find a very useful Registry class file here on IT Ninja. Somewhere..! Or Google for it. I'm pretty sure it's called 'cRegistry'.
Rather than the .RegRead of the Shell object, for consistency you should be using the .GetStringValue method of the StRegProv provider. Details can be found here.
If you're going to be doing much registry scripting, you'll find a very useful Registry class file here on IT Ninja. Somewhere..! Or Google for it. I'm pretty sure it's called 'cRegistry'.
Posted by:
rad33k
7 years ago
It does not work on 32bit machine as in the first part of your script you are trying to get \WOW6432Node\.. which is part of the 64bit OS only.
You should add a detection if this key exists, something like:
iRet = oReg.EnumKey (HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys)
If iRet=0 Then
'Registry key exists
...
...
End If
https://msdn.microsoft.com/en-us/library/windows/desktop/aa372865(v=vs.85).aspx
There are a lot of examples over Internet. Below you can find a little tip how to use it:
You should add a detection if this key exists, something like:
iRet = oReg.EnumKey (HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys)
If iRet=0 Then
'Registry key exists
...
...
End If
In scripting or Visual Basic, the method returns an integer value that is 0 (zero) if successful. If the function fails, the return value is a nonzero error code that you can look up in WbemErrorEnum.On the other hand - why not to use Installer object (as you mentioned that you need to remove MSIs only)?
https://msdn.microsoft.com/en-us/library/windows/desktop/aa372865(v=vs.85).aspx
There are a lot of examples over Internet. Below you can find a little tip how to use it:
dim oInstaller : set oInstaller = CreateObject("WindowsInstaller.Installer")
Dim colProductCodes : set colProductCodes = oInstaller.Products
Dim ProductCode, ProductName, ProductVersion
For Each ProductCode in colProductCodes
ProductName = oInstaller.ProductInfo(ProductCode, "InstalledProductName")
ProductVersion = oInstaller.ProductInfo(ProductCode, "VersionString")
Wscript.Echo ProductName &" " &ProductVersion
Next
Comments:
-
Good catch, on both parts! - anonymous_9363 7 years ago
-
I had some free time so I was able to execute it on a 32bit machine :) - rad33k 7 years ago
-
Thanks VBScab and rad33k. Afetr playing with it for a while, I was able to make it run on both (x64 and x86). If I start looking in the 32bit section first, the script works fine. Not sure why though. Because I thought it should be looping through both the sets of registry keys
Also, this is not just for msi's. I also uninstall exe using this (as long as there is a valid uninstall string) by putting a else condition to uninstall even if itis an exe
Thanks for your advice - techsurfer 7 years ago