Hi All,
I have been working on trying to fix my script but don't know how to output from the function.
My script finds a GUID from the registry and dumps the results to an MSIEXEC command.  I need to put it into a function so it can be called a number of times for different GUID's/applications.
Here is my script.  I'm don't normally do scripts but I have been asked to remove all versions of QuickTime and dependencies from all Corp machines.  If the function is removed and  a variable set as "strName = "QuickTime"" with references to MsiGuid removed and appropriate renaming to strName, the script works.  it might not be the best option, someone else pointed out I should be using stdregprov getstringvalue, but couldn't help out.
Could someone please have a look and help out.  Thanks

On Error Resume Next

Dim strName, WshShell, oReg, keyname

Const HKEY_LOCAL_MACHINE = &H80000002

Set WshShell = CreateObject("WScript.Shell")
Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")

strKeyPath64 = "SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\"
strKeyPath32 = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\"

MsiGuid "QuickTime",""
MsiGuid "Apple Application Support",""
MsiGuid "Apple Mobile Device Support",""

Function  MsiGuid(keyname,subkey)

    oReg.EnumKey HKEY_LOCAL_MACHINE, strKeyPath32, arrSubKeys
    For Each subkey In arrSubKeys
        keyname = ""
        keyname = wshshell.RegRead("HKLM\" & strKeyPath32 & subkey & "\DisplayName")
        If keyname = MsiGuid Then
            MsiGuid = subkey
        End If
    Next
    If MsiGuid Then
        MsgBox "MSIEXEC.EXE /X " & MsiGuid & " /QB!"
        'WshShell.Run "MSIEXEC.EXE /X " & MsiGuid & " /QB!", 1, True
    End If

    oReg.EnumKey HKEY_LOCAL_MACHINE, strKeyPath64, arrSubKeys
    For Each subkey In arrSubKeys
        keyname = ""
        keyname = wshshell.RegRead("HKLM\" & strKeyPath64 & subkey & "\DisplayName")
        If keyname = MsiGuid Then
            MsiGuid = subkey
        End If
    Next
    If MsiGuid Then
        MsgBox "MSIEXEC.EXE /X " & MsiGuid & " /QB!"
        'WshShell.Run "MSIEXEC.EXE /X " & MsiGuid & " /QB!", 1, True
    End If

End Function
Answer Summary:
Cancel
1 Comment   [ + ] Show Comment

Comments

  • Thanks aragorn.2003 and VBScab for your help. I did many hours of reading and testing to adjust aragorn's script so it would uninstall multiple components without making the script multiple times longer. This one is just 2 lines modified to change the object uninstalling.
    Option Explicit
    Dim objWMIService, strComputer, _
    objReg, strKeyPath64, strKeyPath32, arrSubKeys, _
    subkey, sValue1, sValue2, ret1, ret2, ret3, _
    SHL, sDispName1, sDispName2, sDispName3
    ' On Error Resume Next
    strComputer = "."

    Set SHL = CreateObject("WScript.Shell")

    'Constants
    Const HKCU = &H80000001
    Const HKLM = &H80000002
    ' WMI connection to Root CIM
    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
    Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
    'Get installed software
    strKeyPath32 = "Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
    strKeyPath64 = "Software\Microsoft\Windows\CurrentVersion\Uninstall"
    sDispName1 = "QuickTime"
    sDispName2 = "Apple Application Support"
    sDispName3 = "Apple Mobile Device Support"

    Uninstall sDispName1,strKeyPath32
    Uninstall sDispName2,strKeyPath32
    Uninstall sDispName3,strKeyPath64

    Function Uninstall(sValue,strKeyPath)
    objReg.EnumKey HKLM, strKeyPath, arrSubKeys
    For Each subkey In arrSubKeys
    ret1 = objReg.GetStringValue(HKLM, strKeyPath & "\" & subkey, "DisplayName", sValue1)
    ret1 = objReg.GetStringValue(HKLM, strKeyPath & "\" & subkey, "UninstallString", sValue2)

    if ret1 = 0 And ret2 = 0 Then
    'MsgBox(sValue1 & " : " & sValue2)
    ret3 = InStr(sValue1, sValue)

    if ret3 > 0 Then
    'For testing, leave these two MsgBox calls un-rem'd
    'MsgBox(sValue1)
    'MsgBox("msiexec.exe /x " & subkey & " /qn /norestart /l*v ""C:\Windows\temp\" & sValue1 & "_Security_Uninstall.txt")
    SHL.Run "msiexec.exe /x " & subkey & " /qn /norestart /l*v ""C:\Windows\temp\" & sValue1 & "_Security_Uninstall.txt", 1, True
    End If
    End If
    Next
    End Function
    • Two exercises for you. Change the script so that it:

      - reads the changing parameters from the command line (hint: .Arguments property)
      - uses the WindowsInstaller.Installer object instead of shelling out to MSIExec (to give you much better error-checking)

      :-)
Please log in to comment

Answer Chosen by the Author

0
The following script did the job in our environment.

Option Explicit
Dim objWMIService, objItem, colItems, strComputer,  _
  objReg, strKeyPath, arrSubKeys, intDrive, _
  subkey, sValue1, sValue2, ret1, ret2, ret3, ret4, _
  colProcessList, SHL, retpop, colProcess, objProcess
' On Error Resume Next
strComputer = "."
intDrive = 0
Set SHL = CreateObject("WScript.Shell")
killQt()
'Constants
Const HKCU = &H80000001
Const HKLM = &H80000002
' WMI connection to Root CIM
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
'Get installed software
strKeyPath = "Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" 
'Search the registry for PPC modules to remove
objReg.EnumKey HKLM, strKeyPath, arrSubKeys
For Each subkey In arrSubKeys
    ret1 = objReg.GetStringValue(HKLM, strKeyPath & "\" & subkey, "DisplayName", sValue1)
    ret1 = objReg.GetStringValue(HKLM, strKeyPath & "\" & subkey, "UninstallString", sValue2)
    
    if ret1=0 and ret2=0 Then
      'MsgBox(sValue1 & " : " & sValue2)    
      ret3 = InStr(sValue1, "QuickTime")
      
      if ret3>0 Then
        'For testing, leave these two MsgBox calls un-rem'd
        'MsgBox(sValue1)
        'MsgBox("msiexec.exe /x" & subkey & " /qn /norestart /log C:\Windows\KACE\uninstall\Quicktime.txt")
        SHL.Run "msiexec.exe /x" & subkey & " /qn /norestart /log C:\Windows\KACE\uninstall\Quicktime.txt", 1, True
      End If
    End If
Next
Sub killQt()
  Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\.\root\cimv2")
  
  Set colProcess = objWMIService.ExecQuery("Select * from Win32_Process Where Name = 'QuickTimePlayer.exe'")
  For Each objProcess in colProcess
  objProcess.Terminate()
  Next  
End Sub
Answered 04/29/2016 by: aragorn.2003
Red Belt

  • Thanks aragorn.2003. That did the trick, I just expanded out ret to 5 and added the Application and Mobile Device Support as 2 more For loops.
    VBScab - thanks for your comments, I will read more on how to use Function. As I mentioned, I don't normally script and much more interested in MSI tech rather than learning a deprecated scripting language.
    Cheers
Please log in to comment

Answers

0

@OP, For the benefit of your further scripting education, think about how functions work and why, therefore, the code below would never work. Also, your variable usage needs attention. You have used 'subkey' as an input variable for the function then re-use the same variable in the 'For' loop. For guidance with naming your variables, Google "Hungarian notation".

Function MsiGuid(keyname,subkey)

<snipped fluff out>
    If keyname = MsiGuid Then
            MsiGuid = subkey
    End If

End Function

Answered 04/29/2016 by: VBScab
Red Belt

Please log in to comment
0

>more interested in MSI tech rather than learning a deprecated scripting language.
Function usage and variable-naming principles apply across any programming language.

>deprecated
...and yet this is the language you chose to use! I suspect you Googled, found a code snippet and have attempted to re-work it. Perhaps you should have prefixed your search with the word 'powershell'.

Answered 05/03/2016 by: VBScab
Red Belt

  • Hi VBScab, sorry for striking a nerve there with you. True I did use some parts of another script to assist in building my script.
    Powershell is not really used in our environment as it is too hard to get approval and script signing, where VBS seems to be - yep, that's fine, put it out.
Please log in to comment
Answer this question or Comment on this question for clarity