For upgrade code retrieval: How can I find the Upgrade Code for an installed MSI file?
The information below has grown considerably over time and may have become a little too elaborate. How to get product codes quickly? (four approaches):
Use the Powershell "one-liner"
Scroll down for screenshot and step-by-step. Disclaimer also below - minor or moderate risks depending on who you ask. Works OK for me. Any self-repair triggered by this option should generally be possible to cancel. The package integrity checks triggered does add some event log "noise" though. Note! IdentifyingNumber
is the ProductCode
(WMI peculiarity).
get-wmiobject Win32_Product | Sort-Object -Property Name |Format-Table IdentifyingNumber, Name, LocalPackage -AutoSize
Quick start of Powershell: hold Windows key, tap R, type in "powershell" and press Enter
Use VBScript
(script on github.com)Described below under "Alternative Tools" (section 3). This option may be safer than Powershell for reasons explained in detail below. In essence it is (much) faster and not capable of triggering MSI self-repair since it does not go through WMI (it accesses the MSI COM API directly - at blistering speed). However, it is more involved than the Powershell option (several lines of code).
Registry Lookup
Some swear by looking things up in the registry. Not my recommended approach - I like going through proper APIs (or in other words: OS function calls). There are always weird exceptions accounted for only by the internals of the API-implementation:
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall
HKCU\Software\Microsoft\Windows\CurrentVersion\Uninstall
Original MSI File / WiX Source
You can find the Product Code
in the Property table
of any MSI file (and any other property as well). However, the GUID could conceivably (rarely) be overridden by a transform applied at install time and hence not match the GUID the product is registered under (approach 1 and 2 above will report the real product code - that is registered with Windows - in such rare scenarios).
You need a tool to view MSI files. See towards the bottom of the following answer for a list of free tools you can download (or see quick option below): How can I compare the content of two (or more) MSI files?
UPDATE: For convenience and need for speed :-), download SuperOrca without delay and fuss from this direct-download hotlink - the tool is good enough to get the job done - install, open MSI and go straight to the Property table and find the ProductCode
row (please always virus check a direct-download hotlink - obviously - you can use virustotal.com to do so - online scan utilizing dozens of anti-virus and malware suites to scan what you upload).
Orca is Microsoft's own tool, it is installed with Visual Studio and the Windows SDK. Try searching for
Orca-x86_en-us.msi
- underProgram Files (x86)
and install the MSI if found.
- Current path:
C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x86
- Change version numbers as appropriate
And below you will find the original answer which "organically grew" into a lot of detail.
Maybe see "Uninstall MSI Packages" section below if this is the task you need to perform.
UPDATE: If you also need the upgrade code, check this answer: How can I find the Upgrade Code for an installed MSI file? (retrieves associated product codes, upgrade codes & product names in a table output - similar to the one below).
- Can't use PowerShell? See "Alternative Tools" section below.
- Looking to uninstall? See "Uninstall MSI packages" section below.
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). Section 3 under "Alternative Tools" shows an alternative non-WMI way to get the same information using VBScript. 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
The output should be similar to this:
Note! For some strange reason the "ProductCode" is referred to as "IdentifyingNumber" in WMI. So in other words - in the picture above the IdentifyingNumber is the ProductCode.
If you need to run this query remotely against lots of remote computer, see "Retrieve Product Codes From A Remote Computer" section below.
DISCLAIMER (important, please read before running the command!): Due to strange Microsoft design, any WMI call to
Win32_Product
(like the PowerShell command below) will trigger a validation of the package estate. Besides being quite slow, this can in rare cases trigger an MSI self-repair. This can be a small package or something huge - like Visual Studio. In most cases this does not happen - but there is a risk. Don't run this command right before an important meeting - it is not ever dangerous (it is read-only), but it might lead to a long repair in very rare cases (I think you can cancel the self-repair as well - unless actively prevented by the package in question, but it will restart if you call Win32_Product again and this will persist until you let the self-repair finish - sometimes it might continue even if you do let it finish: How can I determine what causes repeated Windows Installer self-repair?).And just for the record: some people report their event logs filling up with MsiInstaller EventID 1035 entries (see code chief's answer) - apparently caused by WMI queries to the Win32_Product class (personally I have never seen this). This is not directly related to the Powershell command suggested above, it is in context of general use of the WIM class Win32_Product.
You can also get the output in list form (instead of table):
get-wmiobject -class Win32_Product
In this case the output is similar to this:
In theory you should just be able to specify a remote computer name as part of the command itself. Here is the same command as above set up to run on the machine "RemoteMachine" (-ComputerName RemoteMachine
section added):
get-wmiobject Win32_Product -ComputerName RemoteMachine | Format-Table IdentifyingNumber, Name, LocalPackage -AutoSize
This might work if you are running with domain admin rights on a proper domain. In a workgroup environment (small office / home network), you probably have to add user credentials directly to the WMI calls to make it work.
Additionally, remote connections in WMI are affected by (at least) the Windows Firewall, DCOM settings, and User Account Control (UAC) (plus any additional non-Microsoft factors - for instance real firewalls, third party software firewalls, security software of various kinds, etc...). Whether it will work or not depends on your exact setup.
UPDATE: An extensive section on remote WMI running can be found in this answer: How can I find the Upgrade Code for an installed MSI file?. It appears a firewall rule and suppression of the UAC prompt via a registry tweak can make things work in a workgroup network environment. Not recommended changes security-wise, but it worked for me.
PowerShell requires the .NET framework to be installed (currently in version 3.5.1 it seems? October, 2017). The actual PowerShell application itself can also be missing from the machine even if .NET is installed. Finally I believe PowerShell can be disabled or locked by various system policies and privileges.
If this is the case, you can try a few other ways to retrieve product codes. My preferred alternative is VBScript - it is fast and flexible (but can also be locked on certain machines, and scripting is always a little more involved than using tools).
wbemtest.exe
.wbemtest.exe
(Hold down the Windows key, tap R, release the Windows key, type in "wbemtest.exe" and press OK).SELECT IdentifyingNumber,Name,Version FROM Win32_Product
and click "Use" (or equivalent - the tool will be localized).WMIExplorer.exe
SELECT IdentifyingNumber,Name,Version FROM Win32_Product
and press Execute.msiinfo.csv
.' Retrieve all ProductCodes (with ProductName and ProductVersion)
Set fso = CreateObject("Scripting.FileSystemObject")
Set output = fso.CreateTextFile("msiinfo.csv", True, True)
Set installer = CreateObject("WindowsInstaller.Installer")
On Error Resume Next ' we ignore all errors
For Each product In installer.ProductsEx("", "", 7)
productcode = product.ProductCode
name = product.InstallProperty("ProductName")
version=product.InstallProperty("VersionString")
output.writeline (productcode & ", " & name & ", " & version)
Next
output.Close
I can't think of any further general purpose options to retrieve product codes at the moment, please add if you know of any. Just edit inline rather than adding too many comments please.
You can certainly access this information from within your application by calling the MSI automation interface (COM based) OR the C++ MSI installer functions (Win32 API). Or even use WMI queries from within your application like you do in the samples above using
PowerShell
,wbemtest.exe
orWMIExplorer.exe
.
If what you want to do is to uninstall the MSI package you found the product code for, you can do this as follows using an elevated command prompt (search for cmd.exe, right click and run as admin):
Option 1: Basic, interactive uninstall without logging (quick and easy):
msiexec.exe /x {00000000-0000-0000-0000-00000000000C}
Quick Parameter Explanation:
/X = run uninstall sequence
{00000000-0000-0000-0000-00000000000C} = product code for product to uninstall
You can also enable (verbose) logging and run in silent mode if you want to, leading us to option 2:
Option 2: Silent uninstall with verbose logging (better for batch files):
msiexec.exe /x {00000000-0000-0000-0000-00000000000C} /QN /L*V "C:\My.log" REBOOT=ReallySuppress
Quick Parameter Explanation:
/X = run uninstall sequence
{00000000-0000-0000-0000-00000000000C} = product code for product to uninstall
/QN = run completely silently
/L*V "C:\My.log"= verbose logging at specified path
REBOOT=ReallySuppress = avoid unexpected, sudden reboot
There is a comprehensive reference for MSI uninstall here (various different ways to uninstall MSI packages): Uninstalling an MSI file from the command line without using msiexec. There is a plethora of different ways to uninstall.
If you are writing a batch file, please have a look at section 3 in the above, linked answer for a few common and standard uninstall command line variants.
And a quick link to msiexec.exe (command line options) (overview of the command line for msiexec.exe from MSDN). And the Technet version as well.
UPDATE: please find a new answer on how to find the upgrade code for installed packages instead of manually looking up the code in MSI files. For installed packages this is much more reliable. If the package is not installed, you still need to look in the MSI file (or the source file used to compile the MSI) to find the upgrade code. Leaving in older section below:
If you want to get the UpgradeCode or other MSI properties, you can open the cached installation MSI for the product from the location specified by "LocalPackage" in the image show above (something like: C:\WINDOWS\Installer\50c080ae.msi
- it is a hex file name, unique on each system). Then you look in the "Property table" for UpgradeCode (it is possible for the UpgradeCode to be redefined in a transform - to be sure you get the right value you need to retrieve the code programatically from the system - I will provide a script for this shortly. However, the UpgradeCode found in the cached MSI is generally correct).
To open the cached MSI files, use Orca or another packaging tool. Here is a discussion of different tools (any of them will do): What installation product to use? InstallShield, WiX, Wise, Advanced Installer, etc. If you don't have such a tool installed, your fastest bet might be to try Super Orca (it is simple to use, but not extensively tested by me).
UPDATE: here is a new answer with information on various free products you can use to view MSI files: How can I compare the content of two (or more) MSI files?
If you have Visual Studio installed, try searching for Orca-x86_en-us.msi
- under Program Files (x86)
- and install it (this is Microsoft's own, official MSI viewer and editor). Then find Orca in the start menu. Go time in no time :-). Technically Orca is installed as part of Windows SDK (not Visual Studio), but Windows SDK is bundled with the Visual Studio install. If you don't have Visual Studio installed, perhaps you know someone who does? Just have them search for this MSI and send you (it is a tiny half mb file) - should take them seconds. UPDATE: you need several CAB files as well as the MSI - these are found in the same folder where the MSI is found. If not, you can always download the Windows SDK (it is free, but it is big - and everything you install will slow down your PC). I am not sure which part of the SDK installs the Orca MSI. If you do, please just edit and add details here.
Similar topics (for reference and easy access - I should clean this list up):