Set ACLs during Web Deployment via MSBuild


Staff member
I have a mostly working web build-and-deploy configuration running in TeamCity, that basically uses MSBuild to automatically deploy the site to a web server. MSDeploy sets everything to Readonly on the target server by default, and I need the AppPool identity to have write access to just one folder.

I found <a href="" rel="nofollow">an article by Kevin leetham</a> that gets me 90% of the way there. Kevin describes how it is possible to hook into the MSBuild Web Publish Pipeline by creating a file called ProjectName.wpp.targets, along these lines:

&lt;Project xmlns=""&gt;
     &lt;!--Extends the AfterAddIisSettingAndFileContentsToSourceManifest action do also set ACLs --&gt;


    &lt;AfterAddIisSettingAndFileContentsToSourceManifest Condition="'$(AfterAddIisSettingAndFileContentsToSourceManifest)'==''"&gt;
  &lt;Target Name="SetCustomACLs" Condition="'$(IncludeCustomACLs)'=='TRUE'"&gt;
    &lt;Message Text="Adding Custom ACls" /&gt;
      &lt;!-- Ensure the AppPool identity has write access to the Files directory --&gt;
      &lt;MsDeploySourceManifest Include="setAcl" Condition="$(IncludeSetAclProviderOnDestination)"&gt;

This is <em>so nearly</em> working that it is driving me crazy. The ACL gets added to the manifest, but the problem is that it generates an absolute path based on the build location, rather than being relative to the IIS web app on the target server. the generated manifest comes out like this (some names have been changed to protect the innocent):

&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;IisApp path="C:\SolutionPath\IisWebAppName\src\MyProjectName\obj\Release_Deploy\Package\PackageTmp" managedRuntimeVersion="v4.0" /&gt;
  &lt;setAcl path="C:\SolutionPath\IisWebAppName\src\MyProjectName\obj\Release_Deploy\Package\PackageTmp" setAclResourceType="Directory" /&gt;
  &lt;setAcl path="C:\SolutionPath\IisWebAppName\src\MyProjectName\obj\Release_Deploy\Package\PackageTmp" setAclUser="anonymousAuthenticationUser" setAclResourceType="Directory" /&gt;
  &lt;setAcl path="C:\SolutionPath\IisWebAppName\src\MyProjectName\obj\Release_Deploy\Package\PackageTmp\files" setAclResourceType="Directory" setAclAccess="Read,Write,Modify" /&gt;

This actually looks correct, the last line is my custom ACL from teh wpp.targets file. However, when MSDeploy sends this to the target server, here's what happens:

2>Start Web Deploy Publish the Application/package to ...
2>Adding sitemanifest (sitemanifest).
2>Adding ACL's for path (IisWebAppName)
2>Adding ACL's for path (IisWebAppName)
2>Adding ACL's for path (C:\SolutionPath\IisWebAppname\src\MyProjectName\obj\Release_Deploy\Package\PackageTmp\files)
2>C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\Web\Microsoft.Web.Publishing.targets(4377,5): Error ERROR_USER_NOT_AUTHORIZED_FOR_SETACL: Web deployment task failed. (Could not complete an operation with the specified provider ("setAcl") when connecting using the Web Management Service. This can occur if the server administrator has not authorized the user for this operation. setAcl

The whole thing falls over on my custom ACL path, which comes out using an absolute path name instead of being relative to <em>IisWebAppName</em>. I cannot figure out why!!

Help please :)