Powershell: Uninstall application by UpgradeCode

前端 未结 1 1915
清歌不尽
清歌不尽 2020-11-27 23:41

When I upgrade / downgrade my application via a Powershell script, I want to first force the uninstallation of the currently installed version before running the new install

相关标签:
1条回答
  • 2020-11-28 00:33

    Since you mention upgrade code, it must mean that you are talking about an MSI file (Windows Installer). As stated by others such an uninstall is normally performed auto-magically by a properly authored MSI package - it is referred to as a major upgrade - which is essentially an uninstall of the existing version of a product and then the install of the newest version.

    The Upgrade Table of the MSI being installed will specify what existing packages on the box will be uninstalled before the new version is installed. In theory you can uninstall any number of existing installations. You can even uninstall a competitive product if you are mad as a hatter. Frankly, and astonishingly, I have never tried to uninstall multiple products during one major upgrade - it is rarely called for. In most cases you uninstall a single, existing product and then install your latest version.

    1. You can modify the Upgrade table using a transform to change how the major upgrade behaves - in other words to make it start or stop uninstalling a specific pre-existing installation.

    2. You can also enumerate all related products that share the same upgrade code by calling this MSI API function (COM - VBScript used as sample):

    Set installer = CreateObject("WindowsInstaller.Installer")
    
    ' Enumerate all products related to "Microsoft Visual C++ 2008 Redistributable - x86 9.0.30729.4148"
    
    ' {AA783A14-A7A3-3D33-95F0-9A351D530011} is the upgrade code
    Set upgrades = installer.RelatedProducts("{AA783A14-A7A3-3D33-95F0-9A351D530011}")
    
    For Each u In upgrades
       MsgBox u, vbOKOnly, "Product Code: "
    Next
    

    Then you can uninstall the products by passing the product code(s) to the msiexec.exe command line (see below for how to do this via MSI API COM automation instead):

    msiexec.exe /x {11111111-1111-1111-1111-11111111111X} /L*V "C:\msilog.log" REBOOT=ReallySuppress
    

    Quick Parameter Explanation (since I recommend this option):

     /X = run uninstall sequence
     /QN = run completely silently
     /L*V "C:\msilog.log"= verbose logging at path specified
     {11111111-1111-1111-1111-11111111111X} = product guid of app to uninstall
     REBOOT=ReallySuppress = prevent reboot without warning (badly authored MSI packages)
    

    If you don't want to uninstall via msiexec.exe, then you can find a myriad of ways to invoke an MSI uninstall here: Uninstalling an MSI file from the command line without using msiexec.

    And you can find the product code of an installed MSI in several different ways: How can I find the product GUID of an installed MSI setup?


    UPDATE: I guess I forgot the obvious, you can uninstall directly via MSI API automation. In the script below we get all products sharing the same upgrade code and then uninstall them in sequence.

    Note that when run silently you should run with admin rights since the UAC may be suppressed and then the uninstall will usually fail (permission denied). Because of this the below script runs the uninstall interactively - allowing UAC prompting and elevation.

    And if it isn't obvious: running this script will uninstall Orca! I use this product as a sample because it is quick to install again (hints on finding the installer quick if you need to towards bottom here - search for "orca"):

    BIG DISCLAIMER:

    The COM method installer.ConfigureProduct does not accept any arguments that allow us to pass in REBOOT=ReallySuppress. This means that a (very) badly authored package which triggers the ScheduleReboot action (or uses some more obscure magic to cause a reboot) - may reboot the system without warning if you run the below script with admin rights and in silent mode.

    There is a newer call ConfigureProductEx which is available as a Win32 function, but it is not exposed via the COM automation interface. If you platform invoke you can use that call - there is a C++ example in section 14 here: Uninstalling an MSI file from the command line without using msiexec. Or you can use the DTF feature from the WiX toolkit (see section 6 in the same link as the C++ example).


    UPDATE July 2018:

    Set installer = CreateObject("WindowsInstaller.Installer")
    installer.InstallProduct "product.msi", "REMOVE=ALL REBOOT=ReallySuppress"
    Set installer = Nothing
    

    Perhaps the above snippet is the best uninstall approach? This should suppress any reboots. I don't have the time or the setup to test it right now (on a Linux box), but I wanted to add it before I forget.


    Original uninstall script:

    Const msiUILevelNone = 2
    Const msiInstallStateAbsent = 2
    
    Set installer = CreateObject("WindowsInstaller.Installer")
    'installer.UILevel = msiUILevelNone ' Disabled to prevent silent uninstall. Now the UAC prompt will show
    
    ' Uninstall Orca, replace upgrade code with yours
    Set products = installer.RelatedProducts("{CFF4D510-79B2-1CCD-0061-5741A0565A76}")
    
    For Each product In products
       ' MsgBox "Product Code: " & product ' Show the product code found, if you want
    
       ' The following call when run silently with admin rights may reboot the system without warning!
       ' This is due to badly authored MSI packages - most packages will not trigger this problem.
       installer.ConfigureProduct product, 0,  msiInstallStateAbsent ' Uninstall product
    
       ' See text above for info on the newer ConfigureProductEx method.
    Next
    
    Set installer = Nothing
    
    MsgBox "Finished" ' Just so we know the script ran if nothing found to uninstall
    

    Some Links:

    • Is there an alternative to GUID when using msiexec to uninstall an application? (uninstall by product name)
    • How can I uninstall an application using PowerShell?
    • How can I use powershell to run through an installer?
    • WIX (remove all previous versions)
    • Wix upgrade goes into maintenance mode and never does upgrade (various ways to uninstall, by product code, by upgrade code, etc...)
    0 讨论(0)
提交回复
热议问题