Run PowerShell script from WiX installer Run PowerShell script from WiX installer powershell powershell

Run PowerShell script from WiX installer


Looks like you have scheduled the CAQuietExec action as deferred. In this case you have to pass the command line to be executed via a CustomActionData property called QtExecDeferred which is written to the execution script. The deferred action can then access the property from the script.

More details at http://wixtoolset.org/documentation/manual/v3/customactions/qtexec.html


I didn't understand Stephen's answer, however I eventually got it working with the help of this blog post.

Here's a summary of the change I made to Greg's code to get it to work:

  • I changed CAQuietExec to WixQuietExec (I'm not sure if this was necessary).

  • In SetProperty I changed the value of the Before attribute from InstallFiles to the Id of the custom action; in Greg's case it would be RunPowerShellScript.

  • Although unrelated to the question, I ended up needing to change the -Version of powershell to 3.0 from 2.0 to prevent an error when running my script.

Here was my actual working code:

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">    <Product Id="*" Name="..." Language="1033" Version="..." Manufacturer="..." UpgradeCode="...">        <Property Id="POWERSHELLEXE">        <RegistrySearch Id="POWERSHELLEXE"            Type="raw"            Root="HKLM"            Key="SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell"            Name="Path" />        </Property>        <Condition Message="This application requires Windows PowerShell.">            <![CDATA[Installed OR POWERSHELLEXE]]>        </Condition>        <SetProperty Id="InstallMongoDB"            Before ="InstallMongoDB"            Sequence="execute"            Value=""[POWERSHELLEXE]" -Version 3.0 -NoProfile -NonInteractive -InputFormat None -ExecutionPolicy Bypass -Command "& '[#MONGODB_INSTALL.PS1]' ; exit $$($Error.Count)"" />        <CustomAction Id="InstallMongoDB" BinaryKey="WixCA" DllEntry="WixQuietExec" Execute="deferred" Return="check" Impersonate="yes" />        <InstallExecuteSequence>            <Custom Action="InstallMongoDB" Before="InstallFinalize"><![CDATA[NOT Installed]]></Custom>        </InstallExecuteSequence>        <Component Id="MONGODB_INSTALL.PS1" Guid="..." DiskId="1">            <File Id="MONGODB_INSTALL.PS1" Name="mongodb-install.ps1" Source="mongodb-install.ps1"/>        </Component>    </Product>    <Fragment>        <Directory Id="TARGETDIR" Name="SourceDir">            <Directory Id="ProgramFilesFolder">                <Directory Id="APPLICATIONFOLDER" Name="...">                    <Directory Id="InstallScripts" Name="InstallScripts">                        <Component Id="MONGODB_INSTALL.PS1" Guid="..." DiskId="1">                            <File Id="MONGODB_INSTALL.PS1" Name="mongodb-install.ps1" Source="mongodb-install.ps1"/>                        </Component>                    </Directory>                </Directory>            </Directory>        </Directory>    </Fragment></Wix>


Only the following example helped mehttps://github.com/damienbod/WiXPowerShellExample/blob/master/SetupWithPowerShellScripts/Product.wxs

you need to add smth similar into your 'Product.wxs'. the 'Value' property of the first 'CustomAction' contains a ps script (create and run a windows service in my case).

<!-- assign the string (ps command) to RegisterPowerShellProperty --><CustomAction Id="RegisterWindowsService"                        Property="RegisterPowerShellProperty"                        Value=""C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -NoLogo -NonInteractive -InputFormat None -NoProfile sc.exe create MyService binpath= 'C:\Program Files (x86)\My service\MyService.exe';sc.exe start MyService"                        Execute="immediate" /><!-- Deferred execution of the above script --><CustomAction Id="RegisterPowerShellProperty"          BinaryKey="WixCA"          DllEntry="CAQuietExec64"          Execute="deferred"          Return="check"          Impersonate="no" /><InstallExecuteSequence>  <!-- On installation we register and start a windows service -->  <Custom Action="RegisterWindowsService" After="CostFinalize">NOT  Installed</Custom>  <Custom Action="RegisterPowerShellProperty" After="InstallFiles">NOT Installed</Custom></InstallExecuteSequence>

you will need to add a reference to 'WixUtilExtension' in order to run the script.