Is there a way to deploy a virtual directory without specifying the app pool username/pass?

Topics: IIS and Web Services
Oct 5, 2010 at 3:40 PM

I already have a virtual directory established and an app pool set up. In a corporate environment, we have service accounts to run the app pools and the username/pass of those accounts are restricted, even in development. I've made great strides in getting Hudson to build the project and create an MSI in a share where we can deploy to integration, however I can't access the service account information to run the install.

I tried to not include the app pool at all, but the MSI fails "The 'AssignVirtualDirectoryToAppPool' task was not given a value for the required parameter 'AppPoolName'." After I include the AppPoolName I also have to provide the VDirUserName/Pass. Is there a setting to either ignore the UserName/Pass or not re-assign AppPools?

I will say that using the BTDF on our CI server has made our multi-developer environment a lot easier. Thanks!

Oct 5, 2010 at 4:21 PM

Thanks, I'm glad that you're finding the Deployment Framework helpful on your projects!

Can you help me understand exactly what behavior you'd like to see?  I'm asking because the vdir deployment doesn't do much besides vdir creation, AppPool creation and assignment of the vdir into the AppPool, then NTFS permission assignment of the physical directory.  If your administrators are already creating and configuring the AppPools and vdirs, then do you need the Framework to deploy to IIS at all?  Or do you sometimes want vdirs created, just not the AppPools?


Oct 5, 2010 at 5:07 PM

I've already got an app pool created by our server team with the appropriate domain qualified service account on it. I don't actually have the password for the account, therefore I can't run the MSI myself in our development environment. All I need is vdir creation (if it doesn't already exist), changing the app pool for the vdir, and copying all the files into the vdir. I don't need to create the app pool. I'm not an IIS expert but I don't believe there's any need for the VDIR_UserName/Pass if I am not creating an app pool.

If the uninstall process doesn't remove the app pool (because you could assume it was being used by other applications) then the creation of the app pool on a re-install would be redundant. It's possible I have my btdfproj file doing more than it should. Pertinent snippets below:

  <VDirList Include="*">
  <VDirList Include="*">

Oct 5, 2010 at 5:47 PM

OK, the best thing for now is to take advantage of the Framework's extensibility to get just what you need.  In your .btdfproj, you can create a new Target called CustomDeployTarget.  In your Program Files\MSBuild\DeploymentFrameworkForBizTalk\5.0 folder, you'll find BizTalkDeploymentFramework.targets.  Open it in Notepad and find the "DeployVDirs" target.  You can see here all of the steps that happen during IIS deployment.  I picked out the pieces that I think you'll need below, which you can paste into your CustomDeployTarget.  I'm assuming that you are not using Windows XP and not using an ISAPI DLL (HTTP receive adapter DLL).

      MetabasePath="$(IISMetabasePath)" Name="%(VDirList.Vdir)" Path="$(MSBuildProjectDirectory)\%(VDirList.Physdir)" />

    <!-- Take the username value from install wizard if doing a formal install -->
    <Exec Command="cacls %(VDirList.Physdir) /E /G $(VDIR_UserName):R" Condition="('$(IisMajorVersion)' == '6' or '$(IisMajorVersion)' == '7') and '$(Configuration)' == 'Server'" />
    <Exec Command="cacls %(VDirList.Physdir)\*.* /E /G $(VDIR_UserName):R" Condition="('$(IisMajorVersion)' == '6' or '$(IisMajorVersion)' == '7') and '$(Configuration)' == 'Server'" />

    <Exec Command="cacls %(VDirList.Physdir) /E /G $(AppPoolAccount):R" Condition="('$(IisMajorVersion)' == '6' or '$(IisMajorVersion)' == '7') and '$(Configuration)' != 'Server'" />
    <Exec Command="cacls %(VDirList.Physdir)\*.* /E /G $(AppPoolAccount):R" Condition="('$(IisMajorVersion)' == '6' or '$(IisMajorVersion)' == '7') and '$(Configuration)' != 'Server'" />

   <!-- Create app pool and place vdir in app pool for win2003 -->
      MetabasePath="$(IISMetabasePath)" VDirName="%(VDirList.Vdir)" AppPoolName="%(VDirList.AppPool)"
      Condition="('$(IisMajorVersion)' == '6' or '$(IisMajorVersion)' == '7')" />

       Command="BTSTask.exe AddResource -Type:WebDirectory -Source:&quot;http://localhost/%(VDirList.Vdir)&quot; -ApplicationName:$(BizTalkAppName)"
       Condition="'$(IncludeCompsAndVDirsAsResources)' == 'true'"/>

With this in place, you'll want to set IncludeVirtualDirectories to false.

If you want the undeploy too, then the .targets file has an UndeployVDirs target as well.  You'll need to copy parts of that into a CustomUndeployTarget in your .btdfproj file.

The tasks that need the username above are calling cacls to assign NTFS permissions.  If you don't care about that, you can just leave out those lines.

Please let me know how this works out for you.


Oct 5, 2010 at 7:12 PM

Wow - I will process all this and integrate it into our solution. Thanks for the help, Tom, I'll let you know if this works for us!

Oct 6, 2010 at 2:31 PM

Are there additional lines I need to paste into the CustomDeplyTarget section? I've copied as above, minus the first two Exec lines (with the VDIR_UserNames) but I get an error when running the MSI locally during the CustomDeployTarget phase:

Error: Application "ESB" not found in configuration database.

Specifically the error is MSB3073: The command "BTSTask.exe AddResource -Type:WebDirectory -Source:"http://localhost/ESB" -ApplicationName:ESB" exited with code 1.

Oct 6, 2010 at 2:52 PM

Ah, right.  CustomDeployTarget is like a pre-deployment extensibility point.  You really need to tie in at the end of the process.  Use CustomPostDeployTarget instead.  That will run after the whole deployment is done, just before the host instances are restarted.  Should work fine for what you are including in it.


Oct 6, 2010 at 4:44 PM
Edited Oct 6, 2010 at 4:46 PM

When in CustomPostDeployTarget, the new VDirs physical locations are not created and no files are generated. The virtual directories do get mapped in IIS, but to folders that don't exist.

Oct 6, 2010 at 4:49 PM
Edited Oct 6, 2010 at 6:23 PM

You're no longer using the built-in support for IIS deployment, so the vdir folder that you're pointing to will not be packaged into the MSI.  In a CustomRedist Target in your .btdfproj, you can copy your vdir into the MSI staging folder:

    The Deployment Framework automatically packages most files into the server install MSI.
    However, if there are special folders or files that you need to include in the MSI, you can
    copy them to the folder $(RedistDir) in the CustomRedist target.
  <Target Name="CustomRedist">
    <MakeDir Directories="$(RedistDir)\TestFiles" />

    <!-- Force MSBuild to expand the item spec into physical file specs -->
    <CreateItem Include="..\TestFiles\**\*.*">
      <Output TaskParameter="Include" ItemName="TestFilesSourceGroup" />

    <Copy DestinationFolder="$(RedistDir)\TestFiles\%(RecursiveDir)" SourceFiles="@(TestFilesSourceGroup)"/>

This is pretty close to what you'll need.  Replace TestFiles with your vdir path.


Oct 6, 2010 at 5:53 PM

Ah perfect - thanks so much for all your help Tom, sorry if I seemed totally dense!

Oct 6, 2010 at 6:26 PM

You're welcome -- this would be tricky to solve on your own without a lot of knowledge about our MSBuild projects.


Mar 21, 2011 at 12:26 PM


Just a comment: Instead of putting parts of DeployVDirs inside CustomPostDeployTarget, wouldn't it be cleaner to override DeployVDirs by copying the whole target to the .btdfproj and then modify it.

Best regards,

Bjørn Egil

Mar 22, 2011 at 4:49 AM

Hi Bjørn,

Thanks!  That's a good point; a clean way to do it and would preserve the order of execution of the targets during the script execution.