Previous Section Table of Contents Next Section

Uninstall Remote MSI Packages

Using WMI to interact with MSI packages seems tricky, but it's not too complicated. Wouldn't it be nice to have a script that shows you which MSI packages are installed on a remote computer, and lets you selectively uninstall one? You could remotely weed out unapproved applications on users' machines, maintain servers, and a host of other useful tasks.

graphics/arrow.gif Remote MSI Uninstall

Listing 31.5 shows the script. It prompts you for a machine name, and then shows you which packages are installed. Note that the one thing this script doesn't do is work against the machine it's running on; that's because WMI doesn't allow you to specify alternate user credentials when accessing the local machine. If you want to uninstall something locally, use the Control Panel!

NOTE

This script runs on Windows NT 4.0, Windows XP, and Windows 2000. However, Windows Server 2003 requires the optional Windows Installer provider, which is included on the Windows Server 2003 CD-ROM.


Listing 31.5. Uninstall.vbs. Uninstalls a remote MSI package.

'get remote computer name

Dim sMachine

sMachine = InputBox("Computer name?")



'get admin credentials

Dim sAdminUser, sPassword

sAdminUser = InputBox("Enter the admin user name.")

sPassword = InputBox("Enter the users password. ")



'get a WMI Locator

Dim oLocator

Set oLocator = CreateObject("WbemScripting.SWbemLocator")



'connect to remote machine

Dim oService

Set oService = oLocator.ConnectServer(sMachine, "root\cimv2", _

    sAdminUser, sPassword)



'get a list of installed products

Dim sMsg, sName

For Each oProduct in GetObject( _

 "winmgmts:{impersonationLevel=impersonate,(Debug)}" _

 ).InstancesOf("win32_Product")



 'is this the product we want?

 sMsg = "Product: " & vbCrLf

 sMsg = sMsg & oProduct.Name

      sMsg = sMsg & vbCrLf & "Uninstall this product?"



 If MsgBox(sMsg, 4) = 6 Then

  sName = oProduct.Name

  Exit For

 End If



Next



'Get the named package

For each oProduct in GetObject( _

 "winmgmts:{impersonationLevel=impersonate}" _

 ).ExecQuery _

      ("Select * from Win32_Product where Name='" & sName & "'")



 'uninstall it

      oProduct.Uninstall



      'done!

      MsgBox "Uninstalled " & sName



Next

This script should run with no alterations in your environment.

graphics/arrow.gif Remote MSI Uninstall-Explained

This script begins by collecting the computer name and administrative credentials. Note that your admin password is displayed in clear text on the screen, but that it isn't transmitted in clear text across the network.


'get remote computer name

Dim sMachine

sMachine = InputBox("Computer name?")



'get admin credentials

Dim sAdminUser, sPassword

sAdminUser = InputBox("Enter the admin user name.")

sPassword = InputBox("Enter the users password. ")

Next, the script fires up WMI and creates a locator. Then, it uses the locator to connect to the specified machine by using the specified credentials. This bit makes the script throw an error if you try to run it against your local machine.


'get a WMI Locator

Dim oLocator

Set oLocator = CreateObject("WbemScripting.SWbemLocator")



'connect to remote machine

Dim oService

Set oService = oLocator.ConnectServer(sMachine, "root\cimv2", _

    sAdminUser, sPassword)

The script now queries WMI for a list of installed packages, or products.


'get a list of installed products

Dim sMsg, sName

For Each oProduct in GetObject( _

 "winmgmts:{impersonationLevel=impersonate,(Debug)}" _

 ).InstancesOf("win32_Product")

The script builds a message that displays the name of the current product.


 'is this the product we want?

 sMsg = "Product: " & vbCrLf

 sMsg = sMsg & oProduct.Name

      sMsg = sMsg & vbCrLf & "Uninstall this product?"

The script uses MsgBox() to ask if this is the product you want to uninstall. If it is, the script sets the product's name into a variable for later use, and stops going through products.


 If MsgBox(sMsg, 4) = 6 Then

  sName = oProduct.Name

  Exit For

 End If



Next

Now, the script gets the named package through another WMI query.


      'Get the named package

For each oProduct in GetObject( _

 "winmgmts:{impersonationLevel=impersonate}" _

 ).ExecQuery _

      ("Select * from Win32_Product where Name='" & sName & "'")

The script executes the package's Uninstall method, which remotely runs the uninstall. Normally, the user on the remote computer doesn't see a thing, although that can differ from package to package.


'uninstall it

     oProduct.Uninstall

Finally, the script displays a message to let you know it finished.


      'done!

      MsgBox "Uninstalled " & sName



Next

Notice that the uninstall routine occurs inside a For Each…Next loop; this uninstalls any packages with the same name as the name you selected. Normally, each package has a unique name, so just one package is uninstalled each time you run this script.

    Previous Section Table of Contents Next Section