Anyone who uses SCCM for application deployments knows the frustration of having to find MSI product codes.
There are a few ways to make this process easier. My preferred method has always been to use the Detection Method tab to extract the product code that I can then copy/paste into the other tabs but when you are creating large amounts of applications this can be a very slow process.
So using PowerShell we can get a list of MSI properties without having to install the MSI or use additional steps in SCCM.
The function in this script can also be used in bigger scripts such as scripts to automate application installation (Something I will post about shortly)
I would like to thank Nickolaj Andersen (http://www.scconfigmgr.com/) for some of the code snippets
############################################################################### #### #### #### #### #### Get-MSIProperties #### #### Version 1.0.0 #### #### Created by: Liam Matthews #### #### #### #### #### ############################################################################### ################################Release notes################################## #### #### ################################### 1.0.0 ##################################### #### - Initial release #### #### #### ############################################################################### <# .SYNOPSIS Get-MSIProperties retrieves all properties for the specified MSI(s) .DESCRIPTION Get-MSIProperties retrieves all properties for the specified MSI(s) .PARAMETER File Single msi file. Can be full path ot file name if in current location Example: C:\Temp\My.msi Example: my.msi .PARAMETER Folder Specify a folder name. The all msi files is any subfolders will be included Example: C:\Temp .PARAMETER Output Outputs the data to a html file in the script launch folder .PARAMETER Log Outputs script running data to log file .EXAMPLE Get-MSIProperties -File My.msi FileName Manufacturer ProductName ProductVersion ProductLanguage ProductCode -------- ------------ ----------- -------------- --------------- ----------- H:\Software\7z920-x64.msi Igor Pavlov 7-Zip 9.20 (x64 edition) 9.20.00.0 1033 {23170F69-40C1-2702-0920-000001000000} The above command gathers msi properties on the specified file .EXAMPLE Get-MSIProperties -Folder C:\Temp -Output FileName Path Manufacturer ProductName ProductVersion ProductLanguage ProductCode -------- ---- ------------ ----------- -------------- --------------- ----------- GoogleChromeStandaloneEnterprise.msi H:\Software\Google\Chrome Google, Inc. Google Chrome 65.240.16509 1033 {80E666DA-3CC1-3476-9968-029D9F1FEB8F} Google Chrome Enterprise 32.0.1700.107.msi H:\Software\Google\Chrome\Enterprise\32.0.1700.107 Google, Inc. Google Chrome 65.169.107 1033 {56B708CC-28A0-3CFC-A83B-BE70E5C4EA18} Google Chrome Enterprise 33.0.1750.154.msi H:\Software\Google\Chrome\Enterprise\33.0.1750.154 Google, Inc. Google Chrome 65.181.32922 1033 {FBD50733-2ABE-3D23-88B4-7B0C0A0ADDA0} Google Earth.msi H:\Software\Google\Earth\Free\7.1.2.2041 Google Google Earth 7.1.2.2041 1033 {4D2A6330-2F8B-11E3-9C40-B8AC6F97B88E} Google Earth Pro.msi H:\Software\Google\Earth\Pro\7.1.2.2041 Google Google Earth Pro 7.1.2.2041 1033 {44FC61F0-2F8A-11E3-8CAE-B8AC6F97B88E} The above command checks if the specified HotFixID is installed on the list of computers contained in a text file and outputs the results to a html file in the script launch folder .NOTES Version 1.0.0 Created by Liam Matthews Credit to Nickolaj Andersen for code snippets (http://www.scconfigmgr.com/) #> [CmdletBinding(DefaultParameterSetName="File")] Param ( # Argument: File [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true,ParameterSetName="File",Position=0)] [String]$File, # Argument: Folder [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true,ParameterSetName="Folder",Position=0)] [String]$Folder = ".\", # Argument: Output [Parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] [Switch]$Output ) #Declaring initial variables $ScriptInfo = Get-PSCallStack $StartTime = Get-Date -Format "HH:mm:ss.fff" $StartDate = Get-Date -Format "MM-dd-yyyy" $StartDateTime = Get-Date -Format "HHmmss" $TZbias = (Get-WmiObject -Query "Select Bias from Win32_TimeZone").bias #Function for fetching MSI properties Function Get-MSIProperty ([string]$Path,[string]$Property) { $WindowsInstaller = New-Object -ComObject WindowsInstaller.Installer $comObjWI = New-Object -ComObject WindowsInstaller.Installer $MSIDatabase = $WindowsInstaller.GetType().InvokeMember("OpenDatabase","InvokeMethod",$Null,$comObjWI,@("$Path",0)) $Query = "SELECT Value FROM Property WHERE Property = '$Property'" $View = $MSIDatabase.GetType().InvokeMember("OpenView","InvokeMethod",$null,$MSIDatabase,($Query)) $View.GetType().InvokeMember("Execute", "InvokeMethod", $null, $View, $null) $Record = $View.GetType().InvokeMember("Fetch","InvokeMethod",$null,$View,$null) $Value = $Record.GetType().InvokeMember("StringData","GetProperty",$null,$Record,1) Return $Value } #Clear output table $Results = @() #Action if file specified IF ($File) { $Manufacturer = Get-MSIProperty -Path $File -Property "Manufacturer" $ProductName = Get-MSIProperty -Path $File -Property "ProductName" $ProductVersion = Get-MSIProperty -Path $File -Property "ProductVersion" $ProductLanguage = Get-MSIProperty -Path $File -Property "ProductLanguage" $ProductCode = Get-MSIProperty -Path $File -Property "ProductCode" #Build results table $Results += New-Object PSObject -Property ([ordered]@{ "FileName" = "$File" "Manufacturer" = "$Manufacturer" "ProductName" = "$ProductName" "ProductVersion" = "$ProductVersion" "ProductLanguage" = "$ProductLanguage" "ProductCode" = "$ProductCode" }) } #Action if folder specified ELSE { #Searching for MSI files in folder $AllMSIFiles = Get-ChildItem $Folder -Recurse -Filter *.msi #Run action for each MSI found foreach ($MSIFullName in $AllMSIFiles) { $Manufacturer = Get-MSIProperty -Path $MSIFullName.FullName -Property "Manufacturer" $ProductName = Get-MSIProperty -Path $MSIFullName.FullName -Property "ProductName" $ProductVersion = Get-MSIProperty -Path $MSIFullName.FullName -Property "ProductVersion" $ProductLanguage = Get-MSIProperty -Path $MSIFullName.FullName -Property "ProductLanguage" $ProductCode = Get-MSIProperty -Path $MSIFullName.FullName -Property "ProductCode" #Build results table $Results += New-Object PSObject -Property ([ordered]@{ "FileName" = $MSIFullName.Name "Path" = $MSIFullName.Directory "Manufacturer" = "$Manufacturer" "ProductName" = "$ProductName" "ProductVersion" = "$ProductVersion" "ProductLanguage" = "$ProductLanguage" "ProductCode" = "$ProductCode" }) } } #Output to file or screen IF ($Output) { #Output to file $Results | ConvertTo-Html | Out-File MSIProperties-$StartDateTime.html } ELSE { #Output to screen $Results | Format-Table }