I carried out an App-V 5 scripting context test recently so that I could prove which context the various App-V 5 scripts run in (user or system) when added or published to a machine or user.
App-V 5 Scripting Test Package
I created a very simple App-V 5 package containing Dependency Walker, and added a shortcut to the executable located at [{ProgramFilesX86}]\DependencyWalker\depends.exe
.
I also added a script to the Scripts folder called alkane.ps1:
param([string]$message)
add-content "c:\temp\alkane.log" "$message $([bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).groups -match "S-1-5-32-544")) $([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)" -ErrorAction Stop
It’s a very simple PowerShell script that takes some text as an argument (I pass this to the script so that I know which scripting section it is running from). Each time the script runs it will output the scripting section is has run from, whether the current scripting context is being run as an administrator, and also what account the script is running under.
In my DeploymentConfig.xml file I added the following UserScripts:
<UserScripts>
<StartProcess RunInVirtualEnvironment="true">
<Path>powershell.exe</Path>
<Arguments>-ExecutionPolicy ByPass -File "[{AppVPackageRoot}]\..\Scripts\alkane.ps1" -message "DeploymentConfig UserScripts StartProcess"</Arguments>
<Wait RollbackOnError="true"/>
<ApplicationId>[{ProgramFilesX86}]\DependencyWalker\depends.exe</ApplicationId>
</StartProcess>
<ExitProcess>
<Path>powershell.exe</Path>
<Arguments>-ExecutionPolicy ByPass -File "[{AppVPackageRoot}]\..\Scripts\alkane.ps1" -message "DeploymentConfig UserScripts ExitProcess"</Arguments>
<Wait RollbackOnError="false"/>
<ApplicationId>[{ProgramFilesX86}]\DependencyWalker\depends.exe</ApplicationId>
</ExitProcess>
<StartVirtualEnvironment RunInVirtualEnvironment="true">
<Path>powershell.exe</Path>
<Arguments>-ExecutionPolicy ByPass -File "[{AppVPackageRoot}]\..\Scripts\alkane.ps1" -message "DeploymentConfig UserScripts StartVirtualEnvironment"</Arguments>
<Wait RollbackOnError="true"/>
</StartVirtualEnvironment>
<TerminateVirtualEnvironment>
<Path>powershell.exe</Path>
<Arguments>-ExecutionPolicy ByPass -File "[{AppVPackageRoot}]\..\Scripts\alkane.ps1" -message "DeploymentConfig UserScripts TerminateVirtualEnvironment"</Arguments>
<Wait RollbackOnError="false"/>
</TerminateVirtualEnvironment>
<PublishPackage>
<Path>powershell.exe</Path>
<Arguments>-ExecutionPolicy ByPass -File "[{AppVPackageRoot}]\..\Scripts\alkane.ps1" -message "DeploymentConfig UserScripts PublishPackage"</Arguments>
<Wait RollbackOnError="true" Timeout="30"/>
</PublishPackage>
<UnpublishPackage>
<Path>powershell.exe</Path>
<Arguments>-ExecutionPolicy ByPass -File "[{AppVPackageRoot}]\..\Scripts\alkane.ps1" -message "DeploymentConfig UserScripts UnpublishPackage"</Arguments>
<Wait RollbackOnError="false" Timeout="30"/>
</UnpublishPackage>
</UserScripts>
and also the following MachineScripts:
<MachineScripts>
<PublishPackage>
<Path>powershell.exe</Path>
<Arguments>-ExecutionPolicy ByPass -File "[{AppVPackageRoot}]\..\Scripts\alkane.ps1" -message "DeploymentConfig MachineScripts PublishPackage"</Arguments>
<Wait RollbackOnError="true" Timeout="30"/>
</PublishPackage>
<UnpublishPackage>
<Path>powershell.exe</Path>
<Arguments>-ExecutionPolicy ByPass -File "[{AppVPackageRoot}]\..\Scripts\alkane.ps1" -message "DeploymentConfig MachineScripts UnpublishPackage"</Arguments>
<Wait RollbackOnError="false" Timeout="30"/>
</UnpublishPackage>
<AddPackage>
<Path>powershell.exe</Path>
<Arguments>-ExecutionPolicy ByPass -File "[{AppVPackageRoot}]\..\Scripts\alkane.ps1" -message "DeploymentConfig MachineScripts AddPackage"</Arguments>
<Wait RollbackOnError="true" Timeout="30"/>
</AddPackage>
<RemovePackage>
<Path>powershell.exe</Path>
<Arguments>-ExecutionPolicy ByPass -File "[{AppVPackageRoot}]\..\Scripts\alkane.ps1" -message "DeploymentConfig MachineScripts RemovePackage"</Arguments>
<Wait RollbackOnError="false" Timeout="60"/>
</RemovePackage>
</MachineScripts>
and in the UserConfig.xml file I added the following UserScripts:
<UserScripts>
<StartProcess RunInVirtualEnvironment="true">
<Path>powershell.exe</Path>
<Arguments>-ExecutionPolicy ByPass -File "[{AppVPackageRoot}]\..\Scripts\alkane.ps1" -message "UserConfig UserScripts StartProcess"</Arguments>
<Wait RollbackOnError="true"/>
<ApplicationId>[{ProgramFilesX86}]\DependencyWalker\depends.exe</ApplicationId>
</StartProcess>
<ExitProcess>
<Path>powershell.exe</Path>
<Arguments>-ExecutionPolicy ByPass -File "[{AppVPackageRoot}]\..\Scripts\alkane.ps1" -message "UserConfig UserScripts ExitProcess"</Arguments>
<Wait RollbackOnError="false"/>
<ApplicationId>[{ProgramFilesX86}]\DependencyWalker\depends.exe</ApplicationId>
</ExitProcess>
<StartVirtualEnvironment RunInVirtualEnvironment="true">
<Path>powershell.exe</Path>
<Arguments>-ExecutionPolicy ByPass -File "[{AppVPackageRoot}]\..\Scripts\alkane.ps1" -message "UserConfig UserScripts StartVirtualEnvironment"</Arguments>
<Wait RollbackOnError="true"/>
</StartVirtualEnvironment>
<TerminateVirtualEnvironment>
<Path>powershell.exe</Path>
<Arguments>-ExecutionPolicy ByPass -File "[{AppVPackageRoot}]\..\Scripts\alkane.ps1" -message "UserConfig UserScripts TerminateVirtualEnvironment"</Arguments>
<Wait RollbackOnError="false"/>
</TerminateVirtualEnvironment>
<PublishPackage>
<Path>powershell.exe</Path>
<Arguments>-ExecutionPolicy ByPass -File "[{AppVPackageRoot}]\..\Scripts\alkane.ps1" -message "UserConfig UserScripts PublishPackage"</Arguments>
<Wait RollbackOnError="true" Timeout="30"/>
</PublishPackage>
<UnpublishPackage>
<Path>powershell.exe</Path>
<Arguments>-ExecutionPolicy ByPass -File "[{AppVPackageRoot}]\..\Scripts\alkane.ps1" -message "UserConfig UserScripts UnpublishPackage"</Arguments>
<Wait RollbackOnError="false" Timeout="30"/>
</UnpublishPackage>
</UserScripts>
App-V 5 Scripting Context Test
In chronological order I added the package, published the package, launched the application, closed the application, unpublished the package and removed the package. I specified various user/deployment XML permutations during add and publish time. The results can be seen below.
App-V 5 Scripting Context Test Results
Test 1
- Apply DeploymentConfig.xml
- Do NOT apply UserConfig.xml
- Publish to user
Script File | Script Section | Script Type | Run As Admin | Context |
---|---|---|---|---|
DeploymentConfig | MachineScripts | AddPackage | True | System |
DeploymentConfig | UserScripts | PublishPackage | False | User |
DeploymentConfig | UserScripts | StartVirtualEnvironment | False | User |
DeploymentConfig | UserScripts | StartProcess | False | User |
DeploymentConfig | UserScripts | ExitProcess | False | User |
DeploymentConfig | UserScripts | TerminateVirtualEnvironment | False | User |
DeploymentConfig | UserScripts | UnpublishPackage | False | User |
DeploymentConfig | MachineScripts | RemovePackage | True | System |
Test 2
- Apply DeploymentConfig.xml
- Do NOT apply UserConfig.xml
- Publish to machine
Script File | Script Section | Script Type | Run As Admin | Context |
---|---|---|---|---|
DeploymentConfig | MachineScripts | AddPackage | True | System |
DeploymentConfig | MachineScripts | PublishPackage | True | System |
DeploymentConfig | UserScripts | StartVirtualEnvironment | False | User |
DeploymentConfig | UserScripts | StartProcess | False | User |
DeploymentConfig | UserScripts | ExitProcess | False | User |
DeploymentConfig | UserScripts | TerminateVirtualEnvironment | False | User |
DeploymentConfig | MachineScripts | UnpublishPackage | True | System |
DeploymentConfig | MachineScripts | RemovePackage | True | System |
Test 3
- Do NOT apply DeploymentConfig.xml
- Apply UserConfig.xml
- Publish to user
Script File | Script Section | Script Type | Run As Admin | Context |
---|---|---|---|---|
UserConfig | UserScripts | PublishPackage | False | User |
UserConfig | UserScripts | StartVirtualEnvironment | False | User |
UserConfig | UserScripts | StartProcess | False | User |
UserConfig | UserScripts | ExitProcess | False | User |
UserConfig | UserScripts | TerminateVirtualEnvironment | False | User |
UserConfig | UserScripts | UnpublishPackage | False | User |
Test 4
- Do NOT specify DeploymentConfig.xml
- Apply UserConfig.xml
- Publish to machine
Error – cannot specify UserConfig.xml if published to machine (-global)
Test 5
- Apply DeploymentConfig.xml
- Apply UserConfig.xml
- Publish to user
Script File | Script Section | Script Type | Run As Admin | Context |
---|---|---|---|---|
UserConfig | UserScripts | PublishPackage | False | User |
UserConfig | UserScripts | StartVirtualEnvironment | False | User |
UserConfig | UserScripts | StartProcess | False | User |
UserConfig | UserScripts | ExitProcess | False | User |
UserConfig | UserScripts | TerminateVirtualEnvironment | False | User |
UserConfig | UserScripts | UnpublishPackage | False | User |
DeploymentConfig | MachineScripts | RemovePackage | True | System |
UserConfig | UserScripts | PublishPackage | False | User |
UserConfig | UserScripts | StartVirtualEnvironment | False | User |
UserConfig | UserScripts | StartProcess | False | User |
UserConfig | UserScripts | ExitProcess | False | User |
UserConfig | UserScripts | TerminateVirtualEnvironment | False | User |
UserConfig | UserScripts | UnpublishPackage | False | User |
Test 6
- Apply DeploymentConfig.xml
- Apply UserConfig.xml
- Publish to machine
Error – cannot specify UserConfig.xml if published to machine
Summary
A summary of these results is depicted in the table below:
Script | Script Section | Script Type | Can Run Inside Virtual Environment? | Potentially RUNs | Context |
---|---|---|---|---|---|
DeploymentConfig | UserScripts | StartProcess | Yes | Multiple | User |
DeploymentConfig | UserScripts | ExitProcess | No | Multiple | User |
DeploymentConfig | UserScripts | StartVirtualEnvironment | Yes | Multiple | User |
DeploymentConfig | UserScripts | TerminateVirtualEnvironment | No | Multiple | User |
DeploymentConfig | UserScripts | PublishPackage | No | Multiple | User/System* |
DeploymentConfig | UserScripts | UnpublishPackage | No | Multiple | User/System* |
DeploymentConfig | MachineScripts | PublishPackage | No | Multiple | System |
DeploymentConfig | MachineScripts | UnpublishPackage | No | Multiple | System |
DeploymentConfig | MachineScripts | AddPackage | No | Once | System |
DeploymentConfig | MachineScripts | RemovePackage | No | Once | System |
UserConfig | UserScripts | StartProcess | Yes | Multiple | User |
UserConfig | UserScripts | ExitProcess | No | Multiple | User |
UserConfig | UserScripts | StartVirtualEnvironment | Yes | Multiple | User |
UserConfig | UserScripts | TerminateVirtualEnvironment | No | Multiple | User |
UserConfig | UserScripts | PublishPackage | No | Multiple | User |
UserConfig | UserScripts | UnpublishPackage | No | Multiple | User |
Additional Notes
- Administrative privileges are required to publish globally, as such globally published packages will be published using the system account
- You can not specify a UserConfig.xml file when publishing globally
- The UserScripts in UserConfig.xml will override the UserScripts in DeploymentConfig.xml if both config files are applied
- Only the StartProcess and StartVirtualEnvironment script types have the option to run inside the virtual environment.
- Only AddPackage and RemovePackage run once in a package lifecycle. Every other script type has the potential to run multiple times, including (Un)PublishPackage (for example, if we use Set-AppVClientPackage to specify a new config file we will need to re-publish the package, but not re-add it.)
- * All UserScripts specified in the DeploymentConfig file will run in a user context when published to a user. However, when published to a machine all UserScripts specified in the DeploymentConfig file will run in a user context with the exception of PublishPackage and UnpublishPackage, which will run under a system context.