MSI UpgradeCode as Detection Method in CM12

Configuration Manager 2012 has a built-in Wizard to use the MSI Product Code in the Detection Method but there is no option to check for the Upgrade Code of a Windows Installer Package.

The Product Code is a GUID that “normally” changes with different versions or languages where the Upgrade Code identifies a Product across Languages and Versions. So it may be helpful (sometimes) to use the Upgrade Code in a Detection Method if it doesn’t matter what version or language is installed.

Product Code: http://msdn.microsoft.com/en-us/library/aa370854(v=vs.85).aspx
Upgrade Code: http://msdn.microsoft.com/en-us/library/aa372375(v=vs.85).aspx

The Installed Upgrade Codes (x86 and x64) are stored in the Registry:

HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UpgradeCodes

But to make it more challenging, the Upgrade Codes are "scrambled" (no idea why !?), so you cannot just search for a key...

To "Scramble" your Code, just take the first 8 Characters and read it from right to left (reverse), then the same with the next 4 Characters , then again with 4 characters and for the rest always take 2 characters and reverse the content:

With PowerShell you can use the following example to get the "scrambled" key:

$UpgradeCode = '{35265AC6-8855-4970-9275-C1E3EDDB46F1}'

$code = @( 8, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2 ) 
$string = $UpgradeCode -creplace '[^0-F]'
$pos = 0
$result = '' 

#Decode 
for($i=0; $i -le $code.Length ; $i++)
{ $arr = $string.substring($pos, $code[$i]) -split ""; 
[array]::Reverse($arr);
$result = $result +($arr -join '').replace(' ',''); 
$pos = $pos + $code[$i] } 

$result

You can then use the resulting key to create a detection rule to measure if the key exists or you can use a custom script in the detection method to check if the Upgrade Code exists:

$UpgradeCode = '{35265AC6-8855-4970-9275-C1E3EDDB46F1}' 

$code = @( 8, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2 ) 
$string = $UpgradeCode -creplace '[^0-F]' 

#Decode 
for($i=0; $i -le $code.Length ; $i++) 
{ $arr = $string.substring($pos, $code[$i]) -split ""; 
[array]::Reverse($arr);
$result = $result +($arr -join '').replace(' ',''); 
$pos = $pos + $code[$i] } 

#Test if key exists 
if(Test-Path `
HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UpgradeCodes\$result)
{ $true } else { $null }