Public/Get-MSIMetaData.ps1

function Get-MSIMetaData {
    <#
    .SYNOPSIS
        Retrieve a specific MSI property value from MSI based installation file.
 
    .DESCRIPTION
        Retrieve a specific MSI property value from MSI based installation file.
 
    .PARAMETER Path
        Specify the full path to a MSI based installation file.
 
    .PARAMETER Property
        Specify the MSI database property to retrieve it's value.
 
    .NOTES
        Author: Nickolaj Andersen
        Contact: @NickolajA
        Created: 2020-01-04
        Updated: 2020-01-04
 
        Version history:
        1.0.0 - (2020-01-27) Function created
    #>
    
    [CmdletBinding(SupportsShouldProcess = $true)]
    param(
        [parameter(Mandatory = $true, HelpMessage = "Specify the full path to a MSI based installation file.")]
        [ValidateNotNullOrEmpty()]
        [System.IO.FileInfo]$Path,

        [parameter(Mandatory = $true, HelpMessage = "Specify the MSI database property to retrieve it's value.")]
        [ValidateNotNullOrEmpty()]
        [ValidateSet("ProductCode", "ProductVersion", "ProductName", "Manufacturer", "ProductLanguage", "FullVersion")]
        [string]$Property
    )
    Process {
        try {
            # Read property from MSI database
            $WindowsInstaller = New-Object -ComObject WindowsInstaller.Installer
            $MSIDatabase = $WindowsInstaller.GetType().InvokeMember("OpenDatabase", "InvokeMethod", $null, $WindowsInstaller, @($Path.FullName, 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)

            # Commit database and close view
            $MSIDatabase.GetType().InvokeMember("Commit", "InvokeMethod", $null, $MSIDatabase, $null)
            $View.GetType().InvokeMember("Close", "InvokeMethod", $null, $View, $null)           
            $MSIDatabase = $null
            $View = $null

            # Return the value
            return $Value
        } 
        catch {
            Write-Warning -Message $_.Exception.Message; break
        }
    }
    End {
        # Run garbage collection and release ComObject
        [System.Runtime.Interopservices.Marshal]::ReleaseComObject($WindowsInstaller) | Out-Null
        [System.GC]::Collect()
    }
}