It’s December 2nd and Christmas is just around the corner! Yesterday Jakob kicked off the Coretech December Calendar with a great post about “Triggering a webhook from a SharePoint workflow using Out-of-the-box Activities” (Check out his blog post here: http://bit.ly/1N16fte).  That was the  first, this is the second post in the Coretech blog series that will continue until December 24th – Christmas Eve! 🙂

In Part 1 (http://bit.ly/1PlnDPr) I explained how you can utilize ConfigMgr Compliance Baselines for uninstalling software like Java, Adobe etc. with the help of PowerShell and WMI. Well in Part 1 we used the Win32_Product class which is not recommended by many as it runs a consistency check against each installation and this can cause real performance issues and in worst case system failure.

Quote from Greg Ramsey blog: http://gregramsey.net/2012/02/20/win32_product-is-evil/


Win32_Product will return some great information about each windows installer-based application.  In fact, you can even view additional properties by running get-wmiobject win32_product | select * . However, even though you called a basic query of the Win32_Product class, you actually performed a consistency check of each installation.

The solution:

So how can we create a workaround for this. Well we can use basic PowerShell scripting and utilize a different class like SMS_InstalledSoftware which we are going to use in this example. There is just one catch, and that is  that SMS_InstalledSoftware do not have a Uninstall Method like Win32_Product has (https://msdn.microsoft.com/en-us/library/cc144824.aspx). So we need a different method for the actual uninstallation part.

The SMS_InstalledSoftware Class belongs to the Asset Intelligence features in ConfigMgr and is not enabled in Windows by default. You need to 1. have the ConfigMgr Agent installed and 2. enable the “Installed Software – Asset Intelligence (SMS_InstalledSoftware)” class under Hardware Inventory and Classes on your Client Setting Policy. Like this:

In your ConfigMgr Console, go to your Client Setting Policy, then Hardware Inventory and choose Set Classes.

image

Enable Installed Software – Asset Intelligence (SMS_InstalledSoftware)

image

Now that is done we can create a Compliance Settings Item and a Compliance Baseline like in Part 1 (http://bit.ly/1PlnDPr), but instead of utilizing WIN32_Product, let us use SMS_InstalledSoftware instead. Just change the Detection Script and Remediation script to the examples below and you should be good to go.

Detection Script:

#-----------------
#Define Variables
#-----------------
$Software = "Java"

#-----------------
#Search software
#-----------------
Get-WmiObject -class SMS_InstalledSoftware -Namespace "root\cimv2\sms" | 
Where-Object {$PSItem.ProductName -like "*$Software*"}

Remediation Script:

<#    
    .NOTES
    ===========================================================================
     Created on:       26.11.2015
     Created by:       Marius A. Skovli
     Organization:     Coretech
     Filename:         UninstallAppsWithWMI.ps1
    ===========================================================================
    .DESCRIPTION
        This Script will search for the software defined as ProductName in the 
        SMS_InstalledSoftware WMI Class store it in a variable ($Product) and uninstall
        the software. In this Example Java has been Used. 
#>

#-----------------
#Define Variables
#-----------------
$Software = "Java"

#-----------------
#Search software
#-----------------
$Product = Get-WmiObject -class SMS_InstalledSoftware -Namespace "root\cimv2\sms" | 
Where-Object {$PSItem.ProductName -like "*$Software*"}

#-----------------
#Uninstall software
#-----------------

    ForEach ($ObjItem in $Product) 
    {

    #-----------------
    #Define Variables
    #-----------------
    $ID = $ObjItem.SoftwareCode
    $SoftwareName = $ObjItem.ProductName

        #-----------------
        #Uninstall 
        #-----------------
        $Uninstall = "/x" + "$ID /qn" 
        $SP = (Start-Process -FilePath "msiexec.exe" $Uninstall -Wait -Passthru).ExitCode

    Write-Output "Uninstalled $SoftwareName"
    }

Write-Output "Done!"

The remediation script will search for the software defined as ProductName in the SMS_InstalledSoftware WMI Class store it in a variable ($Product) and uninstall the software using basic msiexec.exe /x command. If you have multiple Java versions installed it wil run the uninstallation command ForEach java version it finds.

The result when ran from PowerShell:

image

This is a far better method than using Win32_Product. A a big shout-out goes to Kaido Järvemets for helping me on this little project. Smilefjes

Don’t hesitate to comment below if you have any questions or additional thoughts you want to add.

Have a great December –  a Merry Christmas and Happy New Year to you all!