Scripting

A traditional installer unpacks file and registry items and spreads them around the system as required. Under MSIX, these items are unpackaged into an isolated area, and the package Manifest describes any integrations that are required to be present outside of this isolated area (such as shortcuts and file associations).


Traditional installers also tend to perform customizable actions, investigating the environment and making changes based on what it finds. Even if the application vendor’s installer doesn’t do this, quite often the larger organizations that distribute applications to many users tend to either repackage these customizations, or add scripts to do so.


These customizations may be used to perform licensing operations, configure appropriate back-end servers (especially for dev/test/prod), or determine if integrations with additional applications are required.


Out of the box, MSIX does not support installation time customizations, but when you use PSF, you enable scripting. PSF Scripting is configured and controlled via the Json configuration file and implemented by PsfLauncher.


Scripts may only be triggered by two events: the start and the end of a process. Although there is no “install” script trigger, the “RunOnce” feature of the start trigger provides the effect of an installation script. The RunOnce feature writes a small marker in the Application Registry Hive so that subsequent launches will not run the script again.


The scripts for your packages must be written in PowerShell as PS1 files, and if you need to use the “wait” and “stop on error” features, the script must return a “0” to indicate success.


In a script triggered by the start event, the "wait" feature makes the launcher wait for the script to run to completion before starting the target application. When "wait" is requested, there is a timeout value that must be provided (in milliseconds) and is used as the maximum wait time. If this time is exceeded, it is considered an error, and the application will only be launched at that time if “stop on error” was not specified.


Note: You may want to reference file locations in your script that are dependent on the package installation location (which is dependent on the package name and AppX Volume mounting) or where the redirected user profiles are (dependent on the package name and user name).


To help you with this, PsfLauncher supports two pseudo-variables that you can use in the Json file as script arguments. These are:


Pseudo-variableMeaning

%MsixPackageRoot%

The root folder of the installed package.

%MsixWritablePackageRoot%

The user’s LocalAppData is for file redirection for this package.


The PsfLauncher will decode these arguments which can be passed into your script. However, your script should not contain these syntaxes as "environment variables" because they are not; the PsfLauncher must do that decoding and pass the equivalent path as the argument to your script.


PsfLauncher scripting requires an additional file to be placed in the package. This file named “StartingScriptWrapper.ps1”, is part of the PSF and should be placed in the folder alongside the copy of the PsfLauncher. This Ps1 file is used for both the start and the end trigger scripts and its name can not be changed. Also, the Json configuration will only reference the additional Ps1 file that you provide.


PsfLauncher will call StartingScriptWrapper.ps1 with your script filename and arguments from the Json added as command line arguments.StartingScriptWrapper will manage the run of the script for you.


To allow these PowerShell scripts to be executed, you need to adjust the execution policy. You can do this through a Group Policy Object and set it to Unrestricted or RemoteSigned.

There is also an option to request ByPass mode on the script, however, you should not use this if the GPO is in place.

System changes to the execution policy must be performed on both x64 and x86 PowerShell executables.


Some packaging tools, like Advanced Installer, provide you with a predefined support to visually add and configure the scripts in your package, as part of their integration with the Package Support Framework.


Adding PowerShell scripts inside an MSIX, with Advanced Installer
Adding PowerShell scripts inside an MSIX, with Advanced Installer