Back in App-V 4, there was a very useful checkbox labelled ‘Enforce Security Descriptors’, which was checked by default. By default, it would prevent a standard user (or an admin user running without elevation) from writing to locations as C:\ProgramData, C:\Program Files and C:\Windows in the same way as a regular application. Since unticking this box would effectively make App-V ignore all of these permissions and allow users to write to these locations, it quickly became part many people’s standards and templates to leave it unchecked. The benefits are that you spend less time debugging permission based issues for poorly written apps that try to write to these folders, and there are no drawbacks since all changes are redirected to the user’s PKG file, leaving the system unharmed.

Now we have App-V 5 and things work rather differently and the ‘Enforce Security Descriptors’ checkbox is gone and standard users cannot write to any of the normally protected locations. The only exception is your Primary Virtual Application Directory chosen during sequencing time, which is fully writeable (except for certain file extensions such as .exe and .dll).

So far we have been given absolutely no way by Microsoft how to fix this problem. Apparently Microsoft believe that most applications now adhere to their guidelines and do not try to write to such locations, and also that nobody is still using legacy apps these days. I found a Technet forum post discussing the problem and how to work around it, but none of the suggestions worked. Any permission changes to where the application files are stored under C:\ProgramData\AppV are ignored inside the virtual environment. You also cannot change the permissions from inside the bubble as a standard user. After investigation, I discovered that the ACLs for these folders are not simply inherited at runtime, they are copied and stored in the user profile, where they can be changed.

App-V 5 splits the user’s sandbox for each application between two locations - folders that typically roam, such as %APPDATA%, get stored under %APPDATA%\Microsoft\AppV\Client\VFS. Any changes to non-roaming locations, such as Program Files are written to %LOCALAPPDATA%\Microsoft\AppV\Client\VFS. It is under here that the App-V client creates all of the common restricted VFS folders that we are interested in, and it does this when the virtual environment for a particular application is launched for the first time. The folders are also emptied and the default permissions re-applied when the application is repaired.

Example default permissions:

If you change the permissions on those folders to grant the Users group modify permissions, standard users can then write to those locations in the virtual environment. One important thing to note is that you will need to ensure that the folder you want to write to is in the VFS of your package in the first place. There are a few points to be aware of before trying to solve this with a script to modify the permissions:

The owner of each subfolder is set to the Administrators group and the Users group does not have full control; so standard users cannot adjust the permissions directly.

They can however delete and recreate the folders, and the new folders will then inherit full write permissions.

The folders do not exist at add / publish time to it’s not possible to change them with a script running as local system. It may be possible to add them from scratch, but since a repair resets the folders, it’s better to solve this with a script run within StartVirtualEnvironment.

However when the virtual environment initialises, it creates these folders and applies those permissions to the VE before running any StartVirtualEnvironment scripts. Once the VE is running, changes to the permissions from the outside take no effect until the VE is shutdown and restarted. Therefore an application will not see any of the changes applied until it is launched a second time.

I have put together a script (designed to be run outside of the VE at StartVirtualEnvironment) that does the following:

Checks to see if one of the VFS subfolders (APPV_ROOTS) has write access. The -guid switch is used to provide the package GUID.

If it does, assume script has already run or is not required, and quit.

If access is denied, the entire GUID subfolder is renamed, copied back to it’s original name, then the old copy deleted.

If the -warn switch is supplied, a popup box appears to warn the user that the permissions have been set, suggesting that they close and restart the application.

If the -error switch is supplied the behaviour is similar to the above with a different message, and the script exits with an error code, which can be trapped by setting RollbackOnError=True in the xml where you define the script. Use this if the application will not work at all without the permissions being in place to prevent it launching the first time around. Unfortunately the App-V client displays some further nasty error messages when a script returns an error, I don’t know if it’s possible to suppress these yet.

The -name parameter can be used to supply a friendly package name to show on the message box popups. If the user launched lots of apps at once or put them in their startup folder, they might not know where the error is coming from otherwise.

The only mandatory parameter is -guid, which you can find from the very top of the xml file. If you want to make the script error on first launch to prevent the app from loading until the permissions are ready, simply change -warn to -error and set RollbackOnError="true". After running this, all folder permissions inherit from the user’s local appdata folder, which give System, Administrators and the owner (but not the entire Users group) write access:

So please share this around and comment below if you’ve found it useful or have any issues or ideas for improvements!