3 min read

ConfigMgr - Uninstall Application using Configuration Item / Baseline

Good day!
Time for another thing you can do with Configuration Items/Baseline (CI / CB)!

I was at a customer who had the need to find all devices with an application installed, and then uninstall it. And sure, that shouldn't be to hard, but why not just set something up which will actively on a schedule keep looking for it, and uninstall it if found, and do the same if it's reinstalled.

And using a configuration item/baseline we can achieve just that!
I thought about a function that i use a lot during application packaging that i found in a PSADT cheat sheet, which is real awesome btw, that finds uninstall methods for an application after you've installed it. It's located at the bottom!

PSADT snippits/cheatsheet
PSADT snippits/cheatsheet. GitHub Gist: instantly share code, notes, and snippets.

I thought that you must be able to use this as a detection script as well, and it turns out that you can! Thank you Lee Ramsey!


NOTE! This script, as it sits, will not help you get rid of applications installed under the user context, as a script through CI/CB is ran in SYSTEM context.

I'm going to assume your are a bit familiar with creating CI's so were not going to cover that is this post, if you want some help with this, just give me a shout!

First, find a device with the application, and run the function from the PSADT cheat sheet, this will give you the information you need to do the rest.

Secondly, we create a new CI, and as the discovery script, we set the "Get-Uninstaller" function

Function Get-Uninstaller {
    [Cmdletbinding()]
    Param(
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty]
        [String] $SoftwareName
)
    $LocalKey = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
    $MachineKey32 = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*'
    $MachineKey64 = 'HKLM:\SOFTWARE\Wow6432Node\Windows\CurrentVersion\Uninstall\*'

    $Keys = @($LocalKey, $MachineKey32, $MachineKey64)

    Get-ItemProperty -Path $Keys -EA SilentlyContinue | ?{($_.DisplayName -Like "*$Name*") -or ($_.PsChildName -Like "*$Name*")} | Select PsPath,DisplayVersion,DisplayName,UninstallString,InstallSource,InstallLocation,QuietUninstallString,Installdate
}

If((Get-Uninstaller '{MSIPRODCODE}').DisplayName -eq "SoftwareName"){
    Write-Output 1
}
Else{
    Write-Output 0
}

Using this function, you can search for applications using a string which can match any of these properties:

PsPath, DisplayVersion, DisplayName, UninstallString, InstallSource, InstallLocation, QuietUninstallString, Installdate

And for myself i used the MSI-ProductCode of the software.
Just insert your string here:

(Get-Uninstaller 'INSERTSEARCHSTRING')

and then you can alter or use the same property which i did (DisplayName) to match with "SoftwareName", or string of your choosing, just as long as you know what will show up.

(Get-Uninstaller '{MSIPRODCODE}').DisplayName -eq "SoftwareName")

Now you should have a discovery script which will detect the installed application based on your selections, now we need to add a remediation script in order for the deployment to also remove the application, if this is what we want. Remember that you might have to edit this depending on what installer is used, this example is for an application that can be removed using "msiexec.exe"

This is quite simple, and we use the information gathered with the "Get-Uninstaller" function which we ran first on a device to find out what we need.
In this case, we use a MSIPRODUCTCODE as an example, and the rest is quite simple, we just quietly launch msiexec.exe with the script, and pass our uninstall arguments to it.

$MSIUninstallArgs = @(
    "/x"
    "{MSIPRODUCTCODE}"
    "/qn"
    "/norestart"
)

Start-Process "msiexec.exe" -ArgumentList $MSIUninstallArgs -Wait -NoNewWindow

As for the compliance rule, i set it up as the following

Make sure you check to run the remediation script if not compliant

And that's really all there is to it!
Create a CB and add this CI to it, and deploy according to your preferences.

Note! This obviously works best with applications which can be uninstalled silently and without any forced reboots, but, its really up to you how aggressive you want to be!