Scripting is completely different in App-V 5 versus 4.*. Back in December, I wrote this post describing App-V 5 Scripting support to supplement and hopefully clarify the limited information provided by Microsoft. It will take more time than I have for a couple weeks to be able to write down what I learned this week into a comprehensible document, but I can quickly share some simplified highlights. The terms highlighted may not even be the correct terms to use, so please don’t get hung up on the words used there, just the meaning.
1) Windows processes have a Process Environment and a execution context. We can easily distinguish major differences in the process environment (PE) by running the “set” command in a cmd shell to see the values of all of the environment variables. The execution context (EM) refers to the security account (i.e. windows credentials, like your user domain account) that the process is running under.
Generally, a new process receives both from the parent process that creates it, but there are notable exceptions. For example, when you log in, the Winlogon process modifies both when it starts a few processes, including the copy of explorer.exe that is your “desktop shell”. While Winlogon runs with a local system PE and EC, your processes will have your environment variables (like USERNAME, HOMEDRIVE, APPDATA, etc) and use your credentials. A system process, for example, will typically have a USERNAME set to OSNAME$ (where OSNAME is the name of the operating system) and an ADDDATA set to a special system area. The Windows Services Manager also starts services with altered PE and/or EC, depending on the account that the service is registered to run under, such as Network System or a specialized Service Account.
2) In App-V 4, a virtual environment (VE) started by a helper process (sfttray.exe) communicating to a back-end windows service running under the local system context to create the VE and start all of the processes needed.
- When it started the main exe, it did so using the VPE and EM that sfttray had. The VPE was created using the users PE and altering as specified by the virtual environment variables.
- When it started virtual services marked to run under the local system account, it did so using VPE generated by taking the system PE and applying virtual environment variables, and the local system EC.
- When it ran a script, it also created the VPE and EC using the user PE/EC, and started the script in a conhost process.
This meant that scripts always ran using the user’s credentials and that virtual and real user environment variables could be used in the script command line.
3) In App-V 5, there is no helper. The user starts the exe directly, and a filter in the kernel loader intercepts the process loading before the process can be started. This is also handed off to a windows service to create and manage the virtual environment.
- In essence, the started virtual main process gets a VPE and EC very similar to what it had before. (One difference being that the old system added an extra environment variable so you could tell what VE it was in).
- Services work similarly to the old system as well
- Scripts… not so much
In Microsoft and my post, we mention the context that the scripts run under. What this means is:
- In all cases we start with a System PE running in a System EC.
- If running inside the VE, add in the VE environment variables.
- If running in the user context, this means impersonate the user account — in other w ords don’t bring in a user PE and just change in the user EC.
It also means that we don’t have the conhost process in the middle and that you can’t use environment variables in the scripts. To solve the environment variable issue, I introduced version 1 of ScriptLauncher in March.
So when dealing with a difficult app, this wasn’t enough. Short story:
1) I think there is a bug in App-V. If your virtual app contains virtual services, you can’t start a script a VE creation time. It hangs, you can’t kill it, and must reboot the system to terminate it.
2) I built a newer version of ScriptLauncher. It better processes command line arguments, so that paths that include spaces are handled. It also adds a new environment variable to the VPE that the script runs under. I called it %EffectiveUserName% and you can reference that in the script line (or inside the script).
3) To achieve what I needed in the script, I also had to work outside the box. My goal was to inject a user specific file into the virtual environment (a license file). But it turned out that it was the service that needed to see the file, so injections running in the VE under a user EC would not be seen. This is now solved also (a trick I’ll describe another day when a Tee time isn’t looming).
Forgive the typos, etc, but I wanted to get this out!