Get MSI code of installed applications

Fire up Powershell (hold down the Windows key, tap R, release the Windows key, type in “powershell” and press OK) and run the command below to get a list of installed MSI package product codes along with the local cache package path and the product name (maximize the PowerShell window to avoid truncated names).

Before running this command line, please read the disclaimer below (nothing dangerous, just some potential nuisances). If you are trying to uninstall a package there is a section below with some sample msiexec.exe command lines:

get-wmiobject Win32_Product | Format-Table IdentifyingNumber, Name, LocalPackage -AutoSize

MSI Upgrade Code Retrieval (via PowerShell / WMI)

The PowerShell script below should retrieve all related product codes, upgrade codes and product names installed on your machine (table output).

Screenshot of output (full script below):

powershell output

These are the real, live values directly from the Windows Installer database on the machine in question. There is no need for any conversion or interpretation. We are going through the proper APIs.

Technical note!: Be aware that checking properties directly in your original MSI file (property table) or WiX source file, may not match actual installed values since properties can be overridden at install time via transforms (more info below) – or property values specified at the command line. The moral of the story: retrieve property values directly from the system when you can.

Quick disclaimer: In rare cases running the script can trigger a Windows Installer self-repair. Read more in “disclaimer section” below. Just a potential nuisance, but read the disclaimer please.

As a digression, there is also a one-line PowerShell command which will retrieve product codes and upgrade codes only – without the package name included. This might actually suffice for some users (I would recommend the full script below however). There is a screenshot of the output of this one-liner in a section below. Note: this command appears a lot faster than the larger script (the “Value” field is the upgrade code). Also note: product codes without associated upgrade codes will not show up as far as I can tell – they will in the larger script:

gwmi -Query "SELECT ProductCode,Value FROM Win32_Property WHERE Property='UpgradeCode'" | Format-Table ProductCode,Value

To run the full PowerShell script below:

  1. Launch PowerShell (hold down the Windows key, tap R, release the Windows key, type in “powershell” and press OK or hit enter).
  2. Copy the script below in its entirety, and then just right click inside the PowerShell window.
  3. This should start the script, and it will take quite a while to run.
  4. Please report any problems. I am no PowerShell expert – I am a deployment specialist not a coder, but the script should do the job.
  5. Performance note: I just get the whole Win32_Product WMI object
    • Cherry picking properties seemed to actually make it marginally slower (VBScript test).
    • I guess we need to get all rows anyway, and cherry picking columns is just extra lifting?
    • For Win32_Property we filter both rows and columns (upgrade code is just one of many row-types). Be prepared for a slow operation, WMI is very slow.
$wmipackages = Get-WmiObject -Class win32_product
$wmiproperties = gwmi -Query "SELECT ProductCode,Value FROM Win32_Property WHERE Property='UpgradeCode'"
$packageinfo = New-Object System.Data.Datatable

foreach ($package in $wmipackages) 
    $foundupgradecode = $false # Assume no upgrade code is found

    foreach ($property in $wmiproperties) {

        if ($package.IdentifyingNumber -eq $property.ProductCode) {
           [void]$packageinfo.Rows.Add($package.Name,$package.IdentifyingNumber, $property.Value)
           $foundupgradecode = $true

    if(-Not ($foundupgradecode)) { 
         # No upgrade code found, add product code to list
         [void]$packageinfo.Rows.Add($package.Name,$package.IdentifyingNumber, "") 


$packageinfo | Format-table ProductCode, UpgradeCode, Name

# Enable the following line to export to CSV (good for annotation). Set full path in quotes
# $packageinfo | Export-Csv "[YourFullWriteablePath]\MsiInfo.csv"

# copy this line as well
The above post is primarly lifted from and has been archived here for my own future reference

Leave a Response

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.