Remove-MSIApplications not working

Can I please clarify if Remove-MSIApplications uses the entire UninstallString value?

According to the docs:

Enumerates the registry for installed applications matching the specified application name and uninstalls that application using the product code, provided the uninstall string matches “msiexec”.

I am interpreting that as Remove-MSIApplications looking for all matches to the DisplayName, and if it finds one, it checks if the UninstallString starts with “msiexec” and if it does, looks up the product_code and runs the command “msiexec /X product_code”. Is that correct?

I am trying to uninstall all existing versions of Python prior to installing the latest and in the Pre-Installation section I’ve got Remove-MSIApplications -Name “Python” and it errors out.

Granted, Python’s UninstallString in the registry is “msiexec /I” instead of “msiexec /X” but that shouldn’t matter if Remove-MSIApplications is not using the UninstallString.

I’m using the latest (3.9.3) version of PS ADT.

If you are looking at the UninstallString in the registry and the ProductCode it contains, consider using Execute-MSI instead:

Execute-MSI -Action Uninstall -Path '{AC76BA86-7AD7-1033-7B44-AB0000000001}

Sorry, no. I wanted to get clarification of how Remove-MSIApplications work.

I didn’t want to have to go and enumerate all possible matches in the registry for “Python” if Remove-MSIApplications already does that and executes “msiexec /X” instead of executing the value stored in UninstallString (because for Python, the UninstallString contains the wrong command … it has msiexec /I instead of msiexec /X).

in the Pre-Installation section I’ve got Remove-MSIApplications -Name "Python" and it errors out.

Please post the line of code and the error if you can.
I’ll se what I can do for you.

You could use Get-InstalledApplication and see what PSADT sees before running Remove-MSIApplications

Disclaimer: I don’t use Remove-MSIApplications. (I probably should though)

So here’s the Windows Registry entry under HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\{08AC27C6-93AA-4C94-A92B-3E4958C2E71B}

UninstallString REG_EXPAND_SZ "MsiExec.exe /I{08AC27C6-93AA-4C94-A92B-3E4958C2E71B}"

And my PS ADT line looks like this:

MSI-RemoveApplications -Name "PaperCut"

I am assuming that based on the docs, MSI-RemoveApplications will go thru the registry, find PaperCut in the DisplayName of product code {08AC27C6-93AA-4C94-A92B-3E4958C2E71B}, checks if the UninstallString begins with “msiexec” (which it does) and then execute "msiexec /X {08AC27C6-93AA-4C94-A92B-3E4958C2E71B}"

But it doesn’t seem to happen and the old PaperCut is still left there. I suspect it is NOT executing “msiexec /X” but instead executing the value of UninstallString which is "MsiExec.exe /I{08AC27C6-93AA-4C94-A92B-3E4958C2E71B}" which is wrong because it uses /I not /X

/I means install

Some InstallShield packages do an “Install” to show a GUI during the uninstall for the user.

PSADT probably filters out everything but the ProductCode and uses it with MSIEXEC /X

The PSADT log will tell you what it did

I noticed the Registry’s /i vs. /x oddity long ago and wondered wondered about it. Orange guy’s explanation makes sense (run a GUI for uninstall) since many MSIs will automatically do an uninstall if the MSI is found to already be installed. As for PSADT , my experience is that yes, it uses only the product code, ignoring the rest of the uninstall value.

Anyway… Remove-MSI should be working to remove all prior versions - I use it with other apps. However, years ago, I had a similar problem with uninstalling all versions of Java (x86 and x64). Here’s the code I used that worked a treat. If you’re having trouble with Remove-MSI, maybe this code will help.

    $x86 = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
    $x64 = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall'
    $x86Uninstall = Get-ChildItem -Path $x86 | ForEach-Object { Get-ItemProperty -Path $_.PSPath } | Where-Object { $_ -match 'Java ' } | Select-Object -Property UninstallString
    $x64Uninstall = Get-ChildItem -Path $x64 | ForEach-Object { Get-ItemProperty -Path $_.PSPath } | Where-Object { $_ -match 'Java ' } | Select-Object -Property UninstallString
    If ($x86Uninstall) 
      $x86Uninstall = $x86Uninstall.UninstallString -Replace 'msiexec.exe','' -Replace '/I','' -Replace '/X',''
      $x86Uninstall = $x86Uninstall.Trim()
      Write-Log -Message 'Uninstalling older 32-bit version(s)...'
      ForEach ($Ver in $x86Uninstall)
        Start-Process -FilePath 'msiexec.exe' -ArgumentList "/x$Ver /q" -Wait
        Write-Log -Message "Uninstalled x86 version with product code $Ver."
    If ($x64Uninstall) 
      $x64Uninstall = $x64Uninstall.UninstallString -Replace 'msiexec.exe','' -Replace '/I','' -Replace '/X',''
      $x64Uninstall = $x64Uninstall.Trim()
      Write-Log  -Message 'Uninstalling older 64-bit version(s)...'
      ForEach ($Ver in $x64Uninstall)
        Start-Process -FilePath 'msiexec.exe' -ArgumentList "/x$Ver /q" -Wait
        Write-Log -Message "Uninstalled x64 version with product code $Ver."
1 Like