Project Description

Exposes Windows Installer functionality to PowerShell, providing means to query installed product and patch information and to query views on packages.

PowerShell is a powerful command shell that pipes objects - not just text. Because of this ability, you can string practically unrelated commands together in many different ways to work on different types of objects, all built on .NET. You can use all the properties and methods of those objects passed through the pipeline instead of being limited by the text sent to you as with traditional command shells.

This Windows Installer module for PowerShell provides cmdlets ("command-lets") - similar to functions - to query package states, patches registered and applied to products, and more. You can use it to query Windows Installer products and patches installed on your system.

get-msiproductinfo | where { $_.Name -like '*Visual Studio*' }
You can even use it to determine which products installed a particular file on your system.

get-msicomponentinfo `
    | where { $_.Path -like 'C:\Program Files\*\Common7\IDE\devenv.exe'} `
    | get-msiproductinfo
And with new cmdlets in 2.2.0 you can also install, repair, and uninstall products and patches complete with progress information, and warnings and errors direct to the pipeline.

install-msiproduct .\example.msi -destination (join-path $env:ProgramFiles Example)
You can find more Examples and usage in the Documentation.


The following news is tagged from my blog for project information.
 Heath Stewart's blog : psmsi News Feed 
Saturday, June 28, 2014  |  From Heath Stewart's blog : psmsi

Psake (pronounced like Japanese “sake”) is a build automation tool similar to others out there like make, rake, etc., but built using PowerShell as the language of choice. So it should be no surprise that I use it for my Windows Installer PowerShell Module. It’s useful for automating tasks not limited to just calling MSBuild, but also my PowerShell Help compiler (which loads the module in a separate process, thus allowing me to keep building in the same PowerShell host process), and selected tests with MSTest.

When tests fail (and when practicing TDD they often do), it can be hard to identify which tests failed. Not only are my test names long because of the root namespace, but also because all the test results are the same color. This is were psake can really shimmer. With the changes highlighted in commit 079b56f I can wrap the results to shorten the names and add a bit of flare:


The colors were chosen to mimic test results in Visual Studio’s Test Explorer which I normally use for feature-level work. This makes it easy to identify failed tests. Implemented similar to the Exec function in psake, $LASTEXITCODE is set correctly to also work with tasks like git bisect run for finding when a particular test might have been broken (though normally I run all unit tests before committing). The only real disadvantage is having to wait for MSTest to finish before seeing output but, at least for this project, the selected tests don’t take long enough for that to be a problem.

Hopefully you find this little script tip helpful. What sort of customizations do you like to make to your build environment?

Wednesday, July 03, 2013  |  From Heath Stewart's blog : psmsi

Yesterday I released servicing update 2.2.1, which updates 2.2.0 to fix a few bugs and add a few cool new features:

  • You can define the [string] $MsiAttributeColumnFormat variable to dictate how attribute columns should appear. The values you can pass are the same as the enumeration format strings, except that "G" displays the culture-invariant decimal value you would see in version 2.2.0 or even in Orca. Changing the display format does not change the underlying value, so bitwise operators like -band still work.
  • Can't remember the standard attribute column enumeration values? I've been working with Windows Installer for about 14 years and only remember a couple myself. But now it's a little easier to do by adding another property adapter to standard attribute columns that provide attribute properties in the form:"Has" + <attribute enumeration name> (e.g. Component.Attributes.HasRegistryKeyPath). This is also great if you don't really get bitwise operators. See this example for more detail.
  • While really a bug fix, I wanted to call out specifically that registry paths should be mapped correctly to PSPath properties whether running under 32- or 64-bit PowerShell. This was a fun problem and I invite you to look at the source code for the RegistryView class if you're interested.

Version-specific documentation has been added, but the most significant change to the documentation is the complete overhaul of the examples. Apart from removing some old examples using deprecated functionality, I organized the examples into different subsections (on separate pages) based on what sort of actions you'd like to perform. You can suggest any other examples you would like to see - or any other questions or comments - on the discussion tab.

Thursday, June 13, 2013  |  From Heath Stewart's blog : psmsi

Years ago I released PowerShell cmdlets (“command-lets”) that make querying product and patch information easy and robust. Windows PowerShell is a powerful shell that pipes objects – not simply text – and provides full access to the .NET Framework as part of the language (though higher-level constructs are most often better).

Earlier this week I released a new version – version 2.2.0 - of my Windows Installer PowerShell module with great new cmdlets as well as some bug fixes. I’ll be posting more examples online, but have included a few below to give you an idea of what you can do and how they work seamlessly with other PowerShell cmdlets.

What’s Old

You can query what products are installed. Note that with version 2.2.0, the default search context is all accessible contexts (user-unmanaged, user-managed, and machine):


Like most other PowerShell cmdlets, the output is formatted to show the most important information by default but you can view all properties by piping to select-object:

get-msiproductinfo | select *

These cmdlets follow development guidelines that allow you to pipe them to built-in cmdlets like get-childitem (dir) so you could, for example, get the file size of all cached Windows Installer packages (not the installed size, mind you):

(get-msiproductinfo | dir | measure -sum length).sum / 1mb

You can also get patch information from any or all products, as well as component information. Wondering what product package installed a particular file?

get-msicomponentinfo | where { $_.Path -like "*\devenv.exe" }

You can also store those in a variable for further investigation or pipe them to get-msiproductinfo.

But enough with the old stuff. Let's move onto the new stuff.

What’s New

PowerShell has powerful extensibility – known as the Extensible Type System (ETS). You can add methods and properties via code, cmdlets, and XML configuration files. Similar to type descriptors, I’ve created a PSPropertyAdapter that creates typed properties for each column in a table or custom query:

get-msitable example.msi -table File

You'll see all the columns of the file table as properties. This makes it easy to query for, say, all vital files:

get-msitable example.mis -table File | where { $_.Attributes -band 512 }

Cmdlets like get-msisummaryinfo also rely heavily on ETS to adapt the view of common summary information properties to a more customized view based on the file type (product, patch, or transform).

You can also validate product packages that will write rich ICE message objects to the pipeline. What's more is that you can apply transforms or patches - automatically in sequence order - before ICE validation so you can make sure a patch maintains validity.

dir *.msi | test-msiproduct -patch update1.msp, update2.msp -exclude ICE03

Last but certainly not least, I've added cmdlets to install, repair, and uninstall products and patches that integrate with PowerShell in a familiar way by providing progress information and write warnings and errors to the pipeline. This makes it easy to do diagnostics and repairs all from with Windows PowerShell:

dir *.msi | install-msiproduct -chain -target 'C:\Program Files\Example'

Please take a look at more examples on the project web site on CodePlex. I hope you will find these useful and that they may provide value for developing your own cmdlets.

More Information

To suggest improvements or file bugs, please use the bug tracker. Please note that I have decided modifying packages will not be supported since that type of work is best done in your source authoring and compiled by tools like the WiX toolset.

 Heath Stewart's blog : psmsi News Feed 

Last edited Sep 9, 2013 at 11:21 PM by heaths, version 41