Uninstall Software En Masse

Every now and then, you may have the need to uninstall software, not just a single version but all versions of a certain product from your systems; e.g., QuickTime or Adobe Reader. Because these products are common components, you may have many different versions installed across your organization and because of these many different versions, you can’t just use a single command-line to uninstall them all.

Win32_Product
You may see in various forums, blog posts, etc. the recommendation to use something like this:

wmic product where (name="Adobe Reader") call uninstall

Please don’t do this. The Win32_Product class, which this wmic command-line is using, is evil. See Win32_Product Is Evil and Why Win32_Product is Bad News!  for details. Another problem with doing this is that it only works for Windows Installer installations.

The Solution to Uninstall Software En Masse

So how can we address this challenge? Create a script of course.

The uninstall software script I created (still VBScript to account for those systems still without PowerShell) does the following:

  • Searches through the Uninstall key in the registry (both 32-bit and 64-bit on 64-bit OSes).
  • Finds and loops through entries by DisplayName that contain a specified substring.
    • Grabs the Uninstall string from the entry.
    • Fixes up the uninstall string if needed.
      • Replaces /I with /X.
      • Adds /q if it’s not there already.
      • Adds /norestart if it’s not there already.
    • Runs the fixed up uninstall string to uninstall the product [optional].
  • Outputs the number of matching products found to the console/stdout.
  • Runs a hardware inventory [optional]
  • Creates (or appends to) a log file (called Uninstall-Software.log) in the temp directory of the user running the script or the ConfigMgr logs folder if the ConfigMgr agent is detected.

Usage

The uninstall software script presented here takes one parameter (without which the script does almost nothing):

  • /product:”<substring to search for>”

There are also two optional switches

  • /uninstall — if specified actually runs the uninstall string
  • /hwinv — if specified (and the ConfigMgr agent is installed on the system) runs a hardware inventory at the end

For testing purposes, simply don’t specify the uninstall switch. This will cause the log entries to be output to the console in addition to the log file.

If you need to modify the uninstall string fix-ups applied, simply edit the FixupUninstallString subroutine that starts on line 175.

Examples

The following are examples successfully used in a large production environment and deployed using a package and program in ConfigMgr CB (1602):

cscript.exe Uninstall-Software.vbs /product:”Adobe Reader” /uninstall

cscript.exe Uninstall-Software.vbs /product:”Adobe Acrobat Reader” /uninstall

cscript.exe Uninstall-Software.vbs /product:”Quicktime” /uninstall

Using in an Application

You can also use this script in an application by using the following guidelines:

  • Create the application and a deployment type.
  • Specifying one of the above command lines as the Uninstall command line in the deployment type.
  • Use a noop for the install command line, something like the following:
cmd /c echo .
  • Create a global condition that also runs the script except without the /uninstall switch.
  • Set the detection method as this global condition and check for any value greater than 0.
  • Deploy as an Uninstall optionally hiding it from the Software Center completely (as it would look awkward to the user if they see it there).

Using in Compliance Settings

It is also possible to use this script in a compliance item — you will have to increase the compliance item timeout however for it to successfully uninstall anything (https://blogs.msdn.microsoft.com/fei_xias_blog/2013/10/20/system-center-2012-configmgr-using-vbs-to-extend-the-dcm-script-execution-timeout-value/).

To do use the uninstall software script in this way, first modify lines 64, and 66-68. This is because we can’t pass parameters to scripts used in compliance items. Then use the script as both the detection and remediation script in the compliance item (each modified slightly differently per the notes in the script itself). Configure the setting check to check for a value equal to zero for the item to be compliant as anything else is non-compliant and that’s when we want the remediation script to kick in.

Uninstall Software Script (v 1.02)Download

16 Comments

  1. Hey Jason, would it be beneficial to add /qn instead of just /q? I have seen some poorly written uninstallers still display an interactive UI with just /q.

    • Jason

      Could be — it’s all very installer/uninstaller specific. Easy enough to modify as noted in the post.

  2. chris

    Hello,

    Nice script but any time I try to use the /uninstall switch I get “Wrong number of arguments or invalid property assignment ‘WriteLogMsg’ ”
    Erro on linve 154, 6

    “WriteLogMsg MSG_RUNNING_UNINSTALL
    returnCode = g_WshShell.Run (sUninstallString, 0, true)

    • Jason

      DOH. As they say, all code has bugs and you just found one – Thank You. This one is a typo on my part because of the logging I added and didn’t test that code branch. It’s fixed now, please re-download.

  3. chris

    Hello,

    Thank You- in line 155 you put “WriteLogMsg MSG_RUNNING_UNINSTALL 1, g_echoLog”
    But ut should be “WriteLogMsg MSG_RUNNING_UNINSTALL, 1, g_echoLog”

    Otherwise you get “Expected end of statement”

    Great Script by the way.

  4. JJ

    Although you mention ‘deployed using a package and program in ConfigMgr CB (1602)’ I take it that it’s no different if the package ws deployed by ConfigMgr 2012 R2?

  5. André

    Hello,
    Because of adding the v1.02 comment on line 8 the next comment lines are wrong now:
    ‘ Uncomment line 65 (do not modify it)
    ‘ Uncomment lines 67-69 and modfy as needed
    ‘ Comment out lines 50-58
    They should be:
    ‘ Uncomment line 66 (do not modify it)
    ‘ Uncomment lines 68-70 and modify as needed
    ‘ Comment out lines 51-58
    But thanks for the script.

    • Jason

      Yep — whenever I add comments to the header, any internal comments referencing line numbers need to be adjusted. Maybe I need a better way to indicate what to change in the script.

  6. Rob Humby

    Anyone tried using this for Java? It seems to work perfectly, but then when I try and launch any site that uses Java, Internet Explorer immediately encounters a problem and has to close. This is IE11 on Windows 10.

    • Jason

      I can’t say I’ve tried and don’t really know what would explain this behavior other than the normal stupid Java tricks.

    • Erik

      I guess if you’re using it for Java (I do) be sure to close any browsers before uninstalling/ installing or you will end up with broken Java, it’s the usual Java quirks.

  7. XT

    assuming purpose is to remove silently then why not advertise that this script can only work for MSI by design ?

    any applications not packaged as MSI will still be removed with their initial uninstallstring which is most lilely not silent

    • Jason

      Because that’s not correct. The script includes logic to add silent or unattended switches to the command-line. There’s no one universal silent switch though so there’s no way for me to magically account for them all but it is a simple matter for anyone to modify the script slightly to add the necessary switches for whatever software that they are trying to uninstall.

Leave a Comment