Skip to content

Querying source package information

Heath Stewart edited this page Feb 19, 2018 · 1 revision

The get-msitable cmdlets returns records from a database, and with this module those records' column names can be used like properties on the returned objects through the pipeline.

Get all properties defined in a product package

You can easily query a product package (.msi) for those properties defined in the Property table:

get-msitable product.msi -table Property

Get all metadata defined for a patch package

The get-msitable cmdlets can open either a product (.msi) or patch (.msp) package without any additional parameters, so querying a patch for its metadata - like product properties - is simply:

get-msitable patch.msp -table MsiPatchMetadata

Note that only Windows Installer 3.0-style patches define the MsiPatchMetadata table, but you really should be using those anyway.

Get all files with component information

You can also specify a custom query for get-msitable to select, for example, all files and their associated component GUIDs:

get-msitable product.msi -query "select ComponentId, FileName, Sequence from Component, File where Component_ = Component" | sort Sequence

You can see in this example how we can select and sort on the Sequence column like we can with any object property in PowerShell.

Note that column and table names in Windows Installer are case-sensitive.

You can select ambiguous column names by prepending the table name - just like in any Windows Installer query:

get-msitable product.msi -query "select ComponentId, FileName, File.Attributes from Component, File where Component_ = Component"

Get all files added or updated by patches

You can query the installed state of a product - i.e. with all patches applied - using the get-msitable cmdlets as well. For example, you can get a list of all files added or updated by all patches:

$max = get-msiproductinfo "{93489CA8-6656-33A0-A5AC-E0EDEDB17C3E}" | get-msitable -query "select LastSequence from Media" -ignore | sort LastSequence | select -expand LastSequence -last 1
get-msiproductinfo "{93489CA8-6656-33A0-A5AC-E0EDEDB17C3E}" | get-msitable -query "select ComponentId, FileName, Sequence from Component, File where Component_ = Component and Sequence > $max"

In the previous example, the -IgnoreMachineState parameter was passed (passing -ignore is enough to disambiguate the parameter name) initially to get the maximum sequence of the unmodified product package. Then we use that to select all the files with a higher sequence when the patch is applied, which includes added and updated files.

Get all components with registry key paths

You can query records in many interesting ways. If you wanted to find which components in a product package are defined using a registry key path, you could run:

get-msitable product.msi -table Component | where { $_.Attributes -band 4 }

But who can remember all those attributes values? I've been working with Windows Installer since 1.0 was a public beta and I certainly can't.

get-msitable product.msi -table Component | where { $_.Attributes.HasRegistryKeyPath }

This does not change the underlying property type so bitwise comparison operators like -band continue to work.

All you need to do is specify "Has" + the attribute enumeration name from DTF, which is part of the WiX Toolset. To find all attribute names easily without pouring through documentation, just run the following:

get-msitable product.msi -table Component | select -expand Attributes | gm
Clone this wiki locally