App-V 5 Scripting: Change
It is almost easier to pretend you know nothing about App-V 4.x scripting when looking at scripting in 5.0. That is often my first response to many rumblings about difficulty getting scripting set up in 5.0. These rumblings come mostly from users of App-V 4.x. Change is hard, I know, but we have a better set of options and frankly, in my opinion, it’s much better this way in the long run. It is just a paradigm shift that does require somewhat of a translation process for bringing older scripts from 4.x over to 5.0.
No More SCRIPTBODY (Embed in the Package, not the XML)
First of all, there are no more <SCRIPTBODY> elements. Instead of embedding the script inside the XML, the intent is to have the script embedded inside the package in the .\Scripts folder. This is the ideal place for it as it will be one of the default search paths when calling a script. If you have already sequenced a package (or converted a package) and want to add a SCRIPT element into the dynamic configuration, you will need to specify the path to the script interpreter and script file. So in essence you have as the command and argument the script interpreter as the command and the script (and options) as the argument.
Not Enabled by Default
Before you even begin to start testing scripts, you will have to make sure the client is set up to allow for package scripts. The quickest way to do this is through PowerShell using the following
Set-AppvClientConfiguration -EnablePackageScripts $true
You can also do it by GPO or manually in the registry. Always verify this before testing scripts.
Security Context
Some scripts will run in the SYSTEM context or the currently logged on user depending on the scripts package event. Later I’ll discuss workflows that will also help you determine the context (Machine or User) for running the script (which is another new concept in 5.0.) The following table outlines how the security context relates to the package event.
Event |
Runs As |
When the package is added |
Local System |
When the package is published globally |
Local System |
When the package is published to a user |
Current User |
After a Virtual Environment (Package) is built |
Current User |
After a virtual application is started |
Current User |
After a process exits |
Current User |
When the VE shuts down |
Current User |
Right before a package is unpublished to a user |
Current User |
Right before a package is unpublished globally |
Local System |
Right before a package is removed |
Local System |
Package Events?*
You need to forget the concept of PRE and POST events. Scripts can be called based on specific events in the lifecycle of the package. You will need to know at what point you want the script to be triggered. If your script needs to run in a specific context, this will help determine your event. If you decide your script needs to be triggered during application initialization (at the start of the virtual environment, the start of the process, when a process exits) you will need to also specify the specific application, rollback options, and whether you want to run it inside or outside the virtual environment.
*I so want to call this “event trigger” but it would be confusing.
To explain how the PRE and POST Options of before evolved into Package Event Elements – but not directly – look at the table below:
Package Event |
4.6 |
5.0 |
When the package is added |
N/A |
AddPackage |
When the package is published globally |
N/A |
PublishPackage |
When the package is published to a user |
N/A |
PublishPackage |
Before a Package is Streamed |
PRE STREAM |
N/A |
After a Package is Streamed |
POST STREAM |
N/A |
After a Virtual Environment (Package) is built |
N/A |
StartVirtualEnvironment |
When a virtual application is started |
PRE LAUNCH |
N/A – but same effect can be achieved with StartVirtualEnvironment |
After a virtual application is started |
POST LAUNCH |
StartProcess WAIT=TRUE |
After a process exits |
POST SHUTDOWN |
ExitProcess |
When the VE shuts down |
N/A |
TerminateVirtualEnvironment |
Right before a package is unpublished to a user |
N/A |
UnPublishPackage |
Right before a package is unpublished globally |
N/A |
UnPublishPackage |
Right before a package is removed |
N/A |
RemovePackage |
The key is to know what package/app event you want to trigger execution: (AddPackage, PublishPackage, StartVirtualEnvironment, StartProcess, ExitProcess, TerminateVirtualEnvironment, UnPublishPackage, RemovePackage)
Wait Options
In addition to the command <Path> and <Arguments> you have your “Wait” options (Wait, RollbackOnError, Timeout.) If you have a <Wait> element with nothing else, it will default to RollbackOnFailure=”True” and Timeout=0.
Element Flow
When we put it all together, you will see the element flow follows this basic process:
[MACHINE OR USER CONTEXT?]
[EVENT TO TRIGGER EXECUTION?] [IF VE or Process Event – Also the option of running inside the VE]
[MY Command Path]
[MY Command’s arguments]
[My Wait Options]
[Optional AppID EXE w/ tokenized path if this is a Process event]
Where an example of a machine targeted script looks like this:
<MachineScripts>
<PublishPackage>
<Path>PowerShell.exe</Path>
<Arguments>-f file.ps1 </Arguments>
<Wait RollbackOnError="true" Timeout="30"/>
</PublishPackage>
As another example, if a script was targeted for a user, set for PRE LAUNCH/ABORTRESULT=1/PROTECTED=TRUE in 4.x, and was only needed for one app, you could call it this way in 5.0
<UserScripts>
<StartProcess RunInVirtualEnvironment="true">
<Path>cscript</Path>
<Arguments>myscript.vbs</Arguments>
<Wait RollbackOnError="true"/>
<ApplicationId>[{AppVPackageRoot}]\Directory\Subdirectory\App.EXE</ApplicationId>
</StartProcess>
Deployment Configuration and Dynamic User Configuration
Many of the problems with testing scripts come with proper placement in deployment and dynamic configuration files and how they are targeting. Scripts that need to be called during package add and global publishing events should be part of the DeploymentConfig.XML file. These scripts will also run in the context of the local system account so scripts that map drives, for example, should not go here. Those need to be called as a <UserScript> element. I use the following visual workflow to help me determine targeting and publishing.
In the case of global publishing, the deployment configuration also has a UserConfiguration element in addition to MachineConfiguration which means that scripts appearing during these events will apply to all users when the package is published globally. This would be the appropriate place to have scripts which map network drives.
Comments
Anonymous
January 01, 2003
The image has been fixed. Original one had text missing for some weird reason.Anonymous
November 04, 2013
We face a problem with some In House app Those app are configured trough their argument on launch and I would like to run a different script as well Users can receive 1 to 3 of thoses shortcuts but they never run them simultaneously Example (on appv 4.6): "MyApp Config 1" => MyApp.exe /Config:1 (osd has script1 on prelaunch) "MyApp Config 2" => MyApp.exe /Config:2 (osd has script2 on prelaunch) "MyApp Config 3" => MyApp.exe /Config:3 (osd has script3 on prelaunch) Same done on Appv 5.0 App sequenced is MyApp.exe => only 1 Application ID 3 shortcuts (with the same name in the app-v console but anyway I hope it's a bug). As "start process" scripts are linked with AppID and not Shortcuts I cannot setup script to launch with them. The only workaround I found is to point my shortcuts on an old style but still working CMD batch... Is there an another way ? Is it possible to register more than one AppId for the same app ? and how to ?- Anonymous
July 12, 2016
It is possible to apply more then one config file to an application. If you manage your appv5 deployment via a website (hosted on your appv5 server) its possible to go into this and set up a different config files per AD group. Just as you would assign a different OSD to a different AD group in 4.6.
- Anonymous
Anonymous
November 04, 2013
So let me make sure I understand your desire. You have one application but it requires three different settings. You used a universal package but applied the settings through the use of a pre-launch script. Were there 3 different scripts (hence 3 OSD files) or did you user variables within a single script? Why not use StartVirtualEnvironment as the packagevent?Anonymous
November 07, 2013
Yes you correctly understand In 4.6 we had 1 package with 3 "osd" pointing on the same Exe but with different Script / HKLM / whatever on each osd In 5.0 I had no way to differenciate my shortcuts as they are all pointing on the same "application ID" I cannot create my own "application ID" And I can only define 1 "start process" per xml The only way I found to workaround is pointing on different "batches" that do the job and then start the Exe Or create 3 different packagesAnonymous
December 28, 2013
Pingback from How to Prepare for a Migration to App-V 5.0 - Dynamics AX Sustained Engineering - Microsoft Dynamics AX - Microsoft Dynamics CommunityAnonymous
December 29, 2013
This is the first post in a series of posts around migration of App-V from 4.x to 5.0. IntroductionAnonymous
December 29, 2013
Pingback from How to Prepare for a Migration to App-V 5.0 : Windows Server team Blog : The Official Microsoft IIS SiteAnonymous
February 16, 2014
Yes, there is a learning curve with the new release of App-V. This is why it is extremely important thatAnonymous
May 15, 2014
Pingback from Link App-V Packages to “C:Program Files” Directory | ScriptdEEZAnonymous
May 15, 2014
Pingback from Link App-V Packages to “C:Program Files” Directory | ScriptdEEZAnonymous
May 15, 2014
Pingback from Link App-V Packages to “C:Program Files” Directory | ScriptdEEZAnonymous
May 15, 2014
Pingback from Link App-V Packages to “C:Program Files” Directory | ScriptdEEZAnonymous
September 14, 2015
One of the major improvements included in App-V 5.1 is the improved handling of scripts used with App