SCCM Uninstall EXE (No MSI)

I’m not a powershell expert, I just learn as I go so if you have something that works better, I’d love to see it.

I spent a while looking for this solution to an issue. The issue is uninstalling an app while previous versions may be installed whereas the new version doesn’t uninstall the old version('s).

Since it’s not a .MSI, Execute-MSI from my understanding won’t work and it hasn’t worked for me.

The app is deployed through SCCM. Older versions of the app are also deployed through SCCM. We need to find all instances of the old apps and uninstall them. How do we find out which directories the old software is installed to? What if there are multiple directories in SCCM Cache? (*Note… if SCCM Cache was cleared, this won’t work, it will only uninstall what it can find).

Here’s what I did and it works great. I hope this comes in handy.

$AppName = get-childitem -path c:\windows\ccmcache -filter "Appname*.exe" -recurse -file |Select-object -expandProperty fullname
$Counter = $AppName.split(" ").count

$Var = $AppName.Split(" ",$Counter)

While ($Count -lt $Counter){

start-Process -FilePath $Var[$Count] -ArgumentList "/Silent /Uninstall" -Wait
$Count = $Count+1

Again, if there is a better more efficient way to do this, I’d love to see it. I looked just about everywhere and couldn’t find anything so I hope this helps some of you.

Welcome to the forums, @3rdlaw,

you’ve said, that you try to uninstall an app.
So I assume, you’ve deployed an application and not a package through SCCM.

If you put in a valid detection-method in that particular application, (means that exact version is detected only, and no other version), you should have a look at SCCM’s “Supersedence”-Feature.

With a working supersedence, SCCM will have a look if there’s any previously installed application that should be uninstalled, depending if you set the supersedence to uninstall previous apps or not.
(In some cases, you don’t have to uninstall previous installed ones)

Hope this helps!

Have a good start of the week :slight_smile:

Best regards

You can also search the Registry with something like this example for Java. Even though Java uses MSI, this code can still be made to work by splitting the found uninstall string(s) to separate the .EXE from the parameters, then populate variables for -FilePath and -Argument List for use in the Start-Process process.

    $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)...'
      Start-Process -FilePath 'msiexec.exe' -ArgumentList "/$x86Uninstall /q" -Wait
    If ($x64Uninstall) 
      $x64Uninstall = $x64Uninstall.UninstallString -Replace 'msiexec.exe','' -Replace '/I','' -Replace '/X',''
      $x64Uninstall = $x64Uninstall.Trim()
      Write-Log  -Message 'Uninstalling older 64-bit version(s)...'
      Start-Process -FilePath 'msiexec.exe' -ArgumentList "/$x64Uninstall /q" -Wait