Win32_Product WMI Queries are Bad!

  • 14 June 2018
  • Sean Huggans

Just a note for SysAdmins out there writing scripts or automating all the things: never query the Win32_Product class to find software installed on devices. There's better ways, and querying this can/will cause problems!

Why?

Because querying this class in WMI will cause trigger repair installs on every application Windows Installer ever installed. That means every MSI ever installed on the system will perform an automatic/silent repair install - which is bad if things were customized in an install script after the MSI ran, as it will put it back to default state. This can also cause problems if the msi was installed on a network share that is now unreachable (you should never install msi's from network shares anyway). Overall - avoid this.

A Better Way

If you have ConfigMgr in your environment, you can query the Win32Reg_AddRemovePrograms namespace instead! This will provide the info you are looking for.

Another Better Way

You can also write your own loop to iterate through uninstall keys in the registry. You will need to include both 32-bit and 64-bit uninstall locations in order to have a complete inventory here. I am including an example of this below:

Code: 
$TotalSoftware = new-object System.Collections.ArrayList
$TotalSoftwareList = new-object System.Collections.ArrayList
$RegPathList = New-Object System.Collections.ArrayList
$RegPathList.Add("SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall") | out-null
$RegPathList.Add("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall") | out-null
 
# Evaluate Registry for installed software
foreach ($RegPath in $RegPathList)
{
	try
	{
		$RegObject = [microsoft.win32.registrykey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, [Microsoft.Win32.RegistryView]::Default)
		$RegKey = $RegObject.OpenSubKey($RegPath)
		foreach ($Software in $RegKey.GetSubKeyNames())
		{
			$SoftwarePath = "$RegPath\\$Software"
			$SoftwareObject = [microsoft.win32.registrykey]::OpenBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine, [Microsoft.Win32.RegistryView]::Default)
			$SoftwareKey = $RegObject.OpenSubKey($SoftwarePath)
			if ($SoftwareKey.GetValue("DisplayName")) { $DisplayName = $SoftwareKey.GetValue("DisplayName") }
			else { $DisplayName = "Data Not Available" }
			if ($SoftwareKey.GetValue("DisplayVersion")) { $Version = $SoftwareKey.GetValue("DisplayVersion") }
			else { $Version = "0.0.0.0" }
			if ($SoftwareKey.GetValue("Publisher")) { $Publisher = $SoftwareKey.GetValue("Publisher") }
			else { $Publisher = "Data Not Available" }
			$SoftwareObject = New-Object -TypeName PSObject
			$SoftwareObject | Add-Member -MemberType NoteProperty -Name DisplayName -Value $DisplayName
			$SoftwareObject | Add-Member -MemberType NoteProperty -Name Version -Value $Version
			$SoftwareObject | Add-Member -MemberType NoteProperty -Name Publisher -Value $Publisher
			if ($TotalSoftwareList -notcontains $DisplayName)
			{
				$TotalSoftware.Add($SoftwareObject) | Out-Null
			}
			$TotalSoftwareList.Add($DisplayName) | Out-Null
		}
	}
	catch
	{
		# Nothing	
	}
}

Vendor Links

Error | visuaFUSION Systems Solutions Blog

Error message

  • Warning: Cannot modify header information - headers already sent by (output started at /mnt/home/visuafus/public_html/bahusa.net/includes/common.inc:2861) in drupal_send_headers() (line 1551 of /mnt/home/visuafus/public_html/bahusa.net/includes/bootstrap.inc).
  • Error: Call to undefined function mail() in DefaultMailSystem->mail() (line 79 of /mnt/home/visuafus/public_html/bahusa.net/modules/system/system.mail.inc).

Error

The website encountered an unexpected error. Please try again later.