UPDATE: Microsoft have now resolved these permissions issues in App-V 5.0 SP2 HF4: http://support.microsoft.com/kb/2956985
There is still no solution if you need to write any of the restricted filetypes in the VFS however as discussed here: http://www.virtualvibes.co.uk/cow-and-its-exclusions-in-app-v-5-0/
Back in App-V 4, there was a very useful checkbox labelled ‘Enforce Security Descriptors’, which was checked by default. App-V 4 would capture all of the ACL’s containing user permissions and store them within the sequence. By default, it would enforce these and 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. ACL’s are not captured at all, and the ‘Enforce Security Descriptors’ checkbox is gone. Instead, the App-V client uses the same permissions that are applied to the folders outside of the virtual environment. For example, if users cannot write to C:\Program Files normally, they will not be able to write to any VFS (Virtual File System) folders here inside App-V either. The only exception is your Primary Virtual Application Directory chosen during sequencing time, which is fully writeable (although somebody has alerted me that perhaps it’s not, so more investigation is needed here). Also by the way, the registry is fully open to standard users when inside the virtual environment and does not suffer form the same restriction as the file system.
At the moment we have been given absolutely no way given to us by Microsoft how to fix this problem. With App-V 4 or even MSI, permissions could be applied to certain files and folders to allow them to work without requiring full admin rights on the machine. 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. Just like they believed that nobody used the Start Menu or that everybody with an XBox had a stable internet connection! Hopefully they will backtrack on this one too with a bit of pressure!
I found a Technet forum post discussing the problem and how to work around it, but none of the suggestions work. 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 (I didn’t try as an admin).
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 C:\Users\USERNAME\AppData\Roaming\AppV. Any changes to non-roaming locations, such as Program Files are written to the local appdata folder under C:\Users\USERNAME\AppData\Local. 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 folder 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. In fact you will have even more freedom than you did in App-V 4 since you can now create entirely new subfolders under Program Files, whereas in App-V 4 you could only write to subfolders that were created during sequencing!
One important thing to note is that you will only see the folders above that are part of your sequence. If you need write access to a particular VFS folder, you need to ensure that folder is in the VFS within your sequence in the first place, as simply adding it to this local appdata location as an afterthought via a script for example does not work.
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 switch 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.
' VFSCACLS.vbs v1.0.2 (23/06/13)
' Written by Dan Gough © 2013 Aceapp Solutions
On Error Resume Next
Dim objShell, objFSO, args, i, bWarnOnChange, bErrorOnChange, PackageGUID, PackageName, VFSPath, objTempFile
bWarnOnChange = False
bErrorOnChange = False
Set args = Wscript.Arguments
If args.Count = 0 Then
WScript.Echo "USAGE:" & vbCrLf & vbCrLf & "VFSCACLS.vbs -guid <PackageGUID> [-name <ApplicationName>] [-warn] [-error]" & vbCrLf & vbCrLf & _
"-guid : Package GUID." & vbCrLf & vbCrLf &_
"-name : Text to show on title bar of any popup message boxes displayed when using -warn or -error." & vbCrLf & vbCrLf &_
"-warn : Shows a warning message to the user that they may need to restart the application if changes have been made." & vbCrLf & vbCrLf &_
"-error : As above but also exits with an error code of 1 so that this can trigger a script rollback and prevent the app from being launched."
For i = 0 To args.Count - 1
If LCase(args(i)) = "-warn" Or LCase(args(i)) = "/warn" Then bWarnOnChange = True
If LCase(args(i)) = "-error" Or LCase(args(i)) = "/error" Then bErrorOnChange = True
If LCase(args(i)) = "-guid" Or LCase(args(i)) = "/guid" Then
If i < args.Count -1 Then
If Len(args(i+1)) = 36 Then PackageGUID = args(i+1)
If LCase(args(i)) = "-name" Or LCase(args(i)) = "/name" Then
If i < args.Count -1 Then PackageName = args(i+1)
If PackageGUID = Empty Then
WScript.Echo "ERROR: No package GUID specified or invalid value."
Set objShell = WScript.CreateObject("WScript.Shell")
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
VFSPath = objShell.RegRead("HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Local AppData") & "\Microsoft\AppV\Client\VFS\" & PackageGUID
If Err.Number <> 0 Then
WScript.Echo "ERROR: Unable to read registry key HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Local AppData"
If Not objFSO.FolderExists (VFSPath) Then
WScript.Echo "ERROR: Unable to locate folder VFSPath"
Set objTempFile = objFSO.CreateTextFile(VFSPath & "\APPV_ROOTS\_VFSCACLCS_TempFile.txt", True)
If Err.Number <> 0 Then
objFSO.MoveFolder VFSPath, VFSPath & "_old"
objFSO.CopyFolder VFSPath & "_old", VFSPath
objFSO.DeleteFolder VFSPath & "_old", True
If bWarnOnChange Then
MsgBox "Folder permissions have been updated. It is recommended that you close and restart the application.", 48, PackageName
If bErrorOnChange Then
MsgBox "Folder permissions have been updated. Please ignore any errors that may follow and launch the application again.", 64, PackageName
objFSO.DeleteFile VFSPath & "\APPV_ROOTS\_VFSCACLCS_TempFile.txt", True
You can add this script to the default Scripts directory from the Package Files tab of the sequencer. Then add the following to DeploymentConfig.xml:
<Arguments>VFSCACLS.vbs -guid XXX -name "My App" -warn</Arguments>
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 to 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 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. It would be nice to be able to suppress App-V error messages from a failing script and automatically re-launch the application for the user but that presents further challenges!