As a SCCM admin I'm constantly scripting software installs mostly with the Windows Installer MSI format. There are times when I must verify the MSI provided is what it says it is thus this script was born. I got a lot of this code from another source but, for the life of me, I can't manage to find it. I've just prettied it up a little bit.

Download this script here.

<# 
    .SYNOPSIS
        This function retrieves properties from a Windows Installer MSI database. 
    .DESCRIPTION
        This function uses the WindowInstaller COM object to pull all values from the Property table from a MSI.
    .EXAMPLE
        Get-MsiDatabaseProperties 'MSI_PATH' 
    .PARAMETER FilePath
        The path to the MSI you'd like to query
#>
[CmdletBinding()]
param (
    [Parameter(Mandatory=$True,
    ValueFromPipeline=$True,
    ValueFromPipelineByPropertyName=$True,
    HelpMessage='What is the path of the MSI you would like to query?')]
    [IO.FileInfo[]]$FilePath
)

begin {
    $com_object = New-Object -com WindowsInstaller.Installer
}

process {
    try {
        $database = $com_object.GetType().InvokeMember(
            "OpenDatabase",
            "InvokeMethod",
            $Null,
            $com_object,
            @($FilePath.FullName, 0)
        )

        $query = "SELECT * FROM Property"
        $View = $database.GetType().InvokeMember(
            "OpenView",
            "InvokeMethod",
            $Null,
            $database,
            ($query)
        )

        $View.GetType().InvokeMember("Execute", "InvokeMethod", $Null, $View, $Null)

        $record = $View.GetType().InvokeMember(
            "Fetch",
            "InvokeMethod",
            $Null,
            $View,
            $Null
        )

        $msi_props = @{}
        while ($record -ne $null) {
            $msi_props[$record.GetType().InvokeMember("StringData", "GetProperty", $Null, $record, 1)] = $record.GetType().InvokeMember("StringData", "GetProperty", $Null, $record, 2)
            $record = $View.GetType().InvokeMember(
                "Fetch",
                "InvokeMethod",
                $Null,
                $View,
                $Null
            )
        }

        $msi_props

        } catch {
            throw "Failed to get MSI file properties the error was: {0}." -f $_
        }
}

Join the Jar Tippers on Patreon

It takes a lot of time to write detailed blog posts like this one. In a single-income family, this blog is one way I depend on to keep the lights on. I'd be eternally grateful if you could become a Patreon patron today!

Become a Patron!