Mass Uninstall SCCM PowerShell Script by Publisher

Use SCCM or MDT to Uninstall all applications by a specific publisher or other unique ID using the SMS installed software class in WMI and PowerShell.

So that software….

If you have no idea what I’m talking about take a look at this post and it will come clear!

Unfortunately the Client had a huge variety of Versions of one specific piece of software, ranging from 4.1 to 4.3 with loads of revisions in the middle and it installed 3 products!

Usually to script a removal I can easily jump into the SMS software class and find all relevant entries to a specific software version and build the script from there.

Like this:


##Get list of all products installed
$InstalledProducts = Get-WmiObject -Namespace 'root\cimv2\sms' -Class SMS_InstalledSoftware

## Check the matches
$InstalledProducts | where { $_.ARPDisplayName -imatch 'eSigner' }

## Add specific product to variable
$eSigner = $InstalledProducts | where { ($_.ARPDisplayName -eq 'eSigner 4.2') -and ($_.ProductVersion -eq '4.2.111') }

But this although a great way of doing it only allows me to remove specific versions that I know or the client  knows are out there. Using the bellow:

##Get list of all products installed
$InstalledProducts = Get-WmiObject -Namespace 'root\cimv2\sms' -Class SMS_InstalledSoftware

## Add specific product to variable
$eSigner = $InstalledProducts | where { ($_.ARPDisplayName -eq 'eSigner 4.2') -and ($_.ProductVersion -eq '4.2.111') }

## Check its the right product
$eSigner

## Grab tje local package to a variable for the uninstall process
$CachedMSI = $eSigner.LocalPackage

##Start the uninstall with the local package and verbose logging
Start-Process 'msiexec.exe' -ArgumentList "/x $CachedMSI /qn /norestart /L*v %windir%\temp\uninstall_eSigner42.log" -Wait -NoNewWindow

I could have also created some queries/reports find all the specific versions but this would have taken serious time and as the software was critical for BAU, the site and clients requiring it are fresh, scripting was the only way!

Anyway the script…

  • It grabs all software listed in the ‘root\cimv2\SMS’ ‘SMS_InstalledSoftware’ class in WMI.
  • Then it selects out all the Software with a specific Publisher (this can be changed).
  • If there is none it will write the detection key to the registry and then quit with exit code 0.
  • If there is then it sets the detection keys in the registry.
  • Loops through each product of the application installed finding the name of the product and local MSI package.
  • Starts MSIexec.exe with the arguments of local package and logs to the %WINDIR%\temp\uninstall_$packagename.log for each product installed.
  • It also write the name of the product to the detection key and the exit code of that uninstall (use full for troubleshooting).
  • After this it exits with exit code 3010 telling the Config Mgr client that reboot is required.
##Mass Uninstall the Application by unique ID - Publisher
### To Deploy use program string: powershell.exe -Executionpolicy Bypass -File MassUninstallMSI.ps1
### SCCM_OG 16/07/2016

##Enter unique Identifier - Remember to change line  from Publisher if not using that as unique.
$Unique = "Gemalto"
$DetectKey = "HKLM:\SOFTWARE\RSDELL\SCRIPTS\MassRemMSI\$Unique"
function set-detectionKeys()
{
    New-Item -Path HKLM:\SOFTWARE\ -Name RSDELL –Force
    New-Item -Path HKLM:\SOFTWARE\RSDELL -Name SCRIPTS –Force
    New-Item -Path HKLM:\SOFTWARE\RSDELL\SCRIPTS -Name MassRemMSI –Force
    New-Item -Path HKLM:\SOFTWARE\RSDELL\SCRIPTS\MassRemMSI -Name $Unique –Force
   
}

##Get all Applications in SMS namespace
$InstalledProducts = Get-WmiObject -Namespace 'root\cimv2\sms' -Class SMS_InstalledSoftware

#Grab all of those applications with Publisher of....
$AppArray = $InstalledProducts | where { $_.Publisher -like $Unique }

If ($AppArray.Length -eq 0)
{
    set-detectionKeys
    Set-ItemProperty -Path $DetectKey -Name Array -Value 'NoneFound' -Force
    Write-Host "No applcations Found Exiting with code 0" 
    Exit 0
}

Elseif ($AppArray.Length -gt 0)

{
    set-detectionKeys
    #Uninstall the applications found
    for ($i=0; $i -lt $AppArray.Length; $i++)
    {
        &quot;<code>$AppArray[$i]=&quot; + $AppArray[$i].ARPDisplayName
        &quot;</code>$AppArray[$i]=&quot; + $AppArray[$i].Localpackage
        $packagename = $AppArray[$i].ARPDisplayName
        $packagename = $packagename -replace '\s',''
        $log = &quot;/l*v $env:windir\temp\uninstall_$packagename.log&quot;
        $arguments = &quot;/x &quot; + $AppArray[$i].Localpackage + &quot; /qn /norestart $log&quot;
        $Passthru = Start-Process 'msiexec.exe' -ArgumentList $arguments -Wait -NoNewWindow -PassThru
        $Exitcode = [string]$Passthru.ExitCode
        Set-ItemProperty -Path $DetectKey -Name $packagename -Value &quot;ExitCode: $ExitCode&quot; -Force
    }

    Write-Host &quot;Applcations Found and removed. Exiting with code 3010 for reboot.&quot; 
    Exit 3010
}
Else
{
    set-detectionKeys
    Set-ItemProperty -Path $DetectKey -Name Else -Value 'NoneFound' -Force
    Write-Host &quot;No applcations Found Exiting with code 0&quot; 
    Exit 0
}

##The End 🙂
########################################################

Leave a Reply

Your email address will not be published. Required fields are marked *