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 }