WiX Extension for PowerShell Snap-ins

Heath Stewart

To write an installer for your PowerShell snap-in, the PowerShell documentation instructs you to extend the PSSnapIn or CustomPSSnapIn class. When you add your snap-in assembly to the Custom Action view in a Windows Installer Project in Visual Studio, the InstallerClass property should be set to True and your installer class will be run when the Windows Installer package gets installed.

But this results in a managed custom action being run during installation, and its best to avoid running managed custom actions in Windows Installer. How else should you install your PowerShell snap-in?

I have recently added an extension for registering PowerShell snap-ins into Windows Installer XML, or WiX. This does all the things that version 1 of the PSSnapIn class currently does, will be updated to support scenarios using the CustomPSSnapIn class, and maintained with future versions of these classes.

There are a couple of ways of authoring your WiX projects to use the extension: in a single component or in multiple components. You should always include every assembly in its own component, since a component should only ever include a single executable (native assemblies being the exception). The WiX extension for PowerShell snap-ins allows you to specify types and formats files in separate components or in the same component like in the following two examples.

Files in a single component

Probably the most common scenario is to put all your snap-in, types, and formats files in a single component to be installed together, since a component is the most granular installable unit in a Windows Installer package.

<?xml version="1.0" encoding="UTF-8"?>
<!--
  Copyright (c) Microsoft Corporation. All rights reserved.
-->
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:ps="http://schemas.microsoft.com/wix/PSExtension">
  <Product Id="79FB610B-FFC1-423F-8965-3B9270F26CD2" Name="TestPSSnapInProduct" Language="1033" Version="0.0.0.0" Manufacturer="Microsoft Corporation" UpgradeCode="6F19BDC6-621A-4E12-91C6-46A38EFAF79D">
    <Package Description="Test PS SnapIn in a Product" Comments="Test from: wixexamplestestpowershell.1product.wxs" InstallerVersion="200" Compressed="yes" />
 
    <Media Id="1" Cabinet="product.cab" EmbedCab="yes" />
 
    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder" Name="PFiles">
        <Directory Id="TestPSSnapInProductDirectory" ShortName="pssnapin" Name="Test PS SnapIn">
          <Component Id="TestPSSnapInProductComponent" Guid="16E57633-A090-4BB3-863C-95A8D824D4EC" DiskId="1">
            <File Id="WixTasks" Name="WixTasks.dll" Source="$(env.WIX)examplesdataWixTasks.dll" KeyPath="yes">
              <ps:SnapIn Id="wixtasks" AssemblyName="WixTasks, Version=3.0.1605.0, Culture=neutral, PublicKeyToken=9f4be179981a58d1" Description="WiX Tasks" Vendor="Windows Installer XML">
                <ps:FormatsFile FileId="WixTasks.formats" />
                <ps:TypesFile FileId="WixTasks.types" />
              </ps:SnapIn>
            </File>
            <File Id="WixTasks.formats" Name="WixTasks.formats.ps1xml" Source="$(env.WIX)examplesdataWixTasks.formats.ps1xml" />
            <File Id="WixTasks.types" Name="WixTasks.types.ps1xml" Source="$(env.WIX)examplesdataWixTasks.types.ps1xml" />
          </Component>
        </Directory>
      </Directory>
    </Directory>
 
    <Feature Id="TestPSSnapInProductFeature" Title="Test SnapIn Product Feature" Level="1">
      <ComponentRef Id="TestPSSnapInProductComponent" />
    </Feature>
  </Product>
</Wix>

Files in separate components

Including your snap-in, types, and formats files in separate components lets you conditionally install different views and extended members for types returned by your cmdlets.

<?xml version="1.0" encoding="UTF-8"?>
<!--
  Copyright (c) Microsoft Corporation. All rights reserved.
-->
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:ps="http://schemas.microsoft.com/wix/PSExtension">
  <Product Id="88AD7E2C-E86F-4840-AADE-F80B0DA0EB76" Name="TestPSSnapInProduct" Language="1033" Version="0.0.0.0" Manufacturer="Microsoft Corporation" UpgradeCode="6F19BDC6-621A-4E12-91C6-46A38EFAF79D">
    <Package Description="Test PS SnapIn in a Product" Comments="Test from: wixexamplestestpowershell.0product.wxs" InstallerVersion="200" Compressed="yes" />
 
    <Media Id="1" Cabinet="product.cab" EmbedCab="yes" />
 
    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder" Name="PFiles">
        <Directory Id="TestPSSnapInProductDirectory" ShortName="pssnapin" Name="Test PS SnapIn">
          <Component Id="TestPSSnapInProductComponent" Guid="16E57633-A090-4BB3-863C-95A8D824D4EC" DiskId="1">
            <File Id="WixTasks" Name="WixTasks.dll" Source="$(env.WIX)examplesdataWixTasks.dll" KeyPath="yes">
              <ps:SnapIn Id="wixtasks" AssemblyName="WixTasks, Version=3.0.1605.0, Culture=neutral, PublicKeyToken=9f4be179981a58d1" Description="WiX Tasks" Vendor="Windows Installer XML" />
            </File>
          </Component>
          <Component Id="Test PSTypesFileProductComponent" Guid="12E2AC7F-5A52-4188-8CB1-F055F15A3831" DiskId="1">
            <File Id="WixTasks.types" Name="WixTasks.types.ps1xml" Source="$(env.WIX)examplesdataWixTasks.types.ps1xml" KeyPath="yes">
              <ps:TypesFile SnapIn="wixtasks" />
            </File>
          </Component>
          <Component Id="TestPSFormatsFileProductComponent" Guid="B7449799-05D7-40C0-9629-637D4F55CAE9" DiskId="1">
            <File Id="WixTasks.formats" Name="WixTasks.formats.ps1xml" Source="$(env.WIX)examplesdataWixTasks.formats.ps1xml" KeyPath="yes">
              <ps:FormatsFile SnapIn="wixtasks" />
            </File>
          </Component>
        </Directory>
      </Directory>
    </Directory>
 
    <Feature Id="TestPSSnapInProductFeature" Title="Test SnapIn Product Feature" Level="1">
      <ComponentRef Id="TestPSSnapInProductComponent" />
      <ComponentRef Id="TestPSTypesFileProductComponent" />
      <ComponentRef Id="TestPSFormatsFileProductComponent" />
    </Feature>
  </Product>
</Wix>

The next weekly version of WiX v3 after this post date should include this new extension. To use it, author your source files as shown in the examples above and pass the extension to candle.exe so that the compiler knows how to parse and process the extension elements. You do not currently need to pass the extension to light.exe, but it is good practice to do so and will not noticeably impact linking.

candle.exe product.wxs –ext WixPSExtension
light.exe product.wixobj –ext WixPSExtension

0 comments

Discussion is closed.

Feedback usabilla icon