/build/static/layout/Breadcrumb_cap_w.png

Scripting Question


VBScript not working on a 32-bit machine

02/09/2017 1208 views
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?

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

Comments


All Answers

0
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'.
Answered 02/09/2017 by: VBScab
Red Belt

0
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
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


Answered 02/09/2017 by: rad33k
Fourth Degree Brown Belt

  • Good catch, on both parts!
    • I had some free time so I was able to execute it on a 32bit machine :)
      • 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