Use PowerShell to Uninstall an Application – Comparing WMI vs. a Registry Scan

If you have ever scanned the list of currently installed programs using the WMI Win32_Product class, you’ve noticed that the scan runs slow! This always frustrates me. It seems that WMI attempts to reconfigure every installed product. Even the simplest query can take minutes to run. Here is an example:

$app = Get-WmiObject -Class Win32_Product -Filter “Name like ‘%\\iCloud\\%'”;

On my workstation, this query took over two minutes to complete. A quick check of the events in my Application Event Log shows over 300 events from MsiInstaller with a message similar to this one: Windows Installer reconfigured the product. Add an uninstall command to uninstall iCloud:

$app = Get-WmiObject -Class Win32_Product -Filter “Name like ‘%\\iCloud\\%'”;$app.Uninstall() | out-string;

There is a faster way to search for an installed application. The  registry key Uninstall contains all installed applications.

set-location HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall;$Results = Get-ChildItem | foreach-object { $_.GetValue(“DisplayName”) }

All currently installed applications will be displayed. Fast huh? Put this registry scan along with WMI uninstall, and you can uninstall any MSI using PowerShell very quickly. The function was pieced together from a few sources online, the most helpful was Use PowerShell to Find and Uninstall Software. Here is the function:

function UninstallInstalledMSI($MSIName) {
	$Results = "";
	if ((!$MSIName) -or ($MSIName.TrimEnd() -eq "")) { return $false; }
	#Define the variable to hold the registry paths used by 32 and 64 bit
	$registry = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall","SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
	foreach($UninstallKey in $registry){
		$computername="SERVERNAME";
		#Create an instance of the Registry Object and open the HKLM base key
		$reg=[microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine',$computername) 
		#Drill down into the Uninstall key using the OpenSubKey Method
		$regkey=$reg.OpenSubKey($UninstallKey) 
		#Retrieve an array of string that contain all the subkey names
		$subkeys=$regkey.GetSubKeyNames() 
		#Open each Subkey and use GetValue Method to return the required values for each
		foreach($key in $subkeys){
			$thisKey=$UninstallKey+"\\"+$key 

			$thisSubKey=$reg.OpenSubKey($thisKey) 

			if ($($thisSubKey.GetValue("DisplayName")) like '%$MSIName%') {

				$classKey="IdentifyingNumber=`"$key`",Name=`"$($thisSubKey.GetValue("DisplayName"))`",version=`"$($thisSubKey.GetValue("DisplayVersion"))`"";
				$Results += ([wmi]"Win32_Product.$classkey").uninstall() | out-string;

			}
		} 
	}
	return $Results;
}
$Results = UninstallInstalledMSI("iCloud");if($Results) { $Results; }


Leave a Reply