Out of the box, basic web project deployment is taken care of as soon as web port is configured in BizTalk application and MSI is exported. When running, this MSI will create web directory under default IIS web site and copy all files found in this directory on the build server. Now, what if we want to change physical location of web directory to be different from the build server, or limit set of files that must be deployed, or deploy precompiled web project (by source files get deployed)? There are ways to achieve these goals.


To add web directory to an application when building a package we can use following command:

BtsTask.exe AddResource -Type:System.BizTalk:WebDirectory

 /Source:value /Destination:value

There’s one problem though: the Destination parameter defines only virtual path. The physical path will be the same as on the source machine where the package is built. We can change it by creating IIsVirtualDir metabase entry with Path property set to desired physical location prior to calling AddResource command. This will still leave us with physical path hardwired into the msi without ability to alter it at the install time. Another problem with this approach is that all files from source directory will be added to the package as is (not compiled source files) which is not always desired.


More flexible way would be to take full control of the web project installation process and here is how.

Package build:

1)       Compile web project in desired mode to designated folder (in this example PrecompiledPath) using aspnet_compiler.exe. There are three compilation modes available for web projects: default no precompilation (source code, will be compiled on request), precompiled updateable, binaries only. Pasting following code into project’s build subscript (i.e. %AppName%_build_projects.bat in the previous post) will take care of this step:


IF %BuildMode%==Debug (SET WebEmitDebug=-d)

aspnet_compiler -v /%VirtDirName% -f -fixedNames %WebEmitDebug% “PrecompiledPath


2)       Add required only files from this folder to the package using BtsTask AddResource. One way of doing this:


FOR %%F IN (“PrecompiledPath\*.*”) DO btstask AddResource /A:%AppName% /Type:System.BizTalk:File /Source:”%%F” /Destination:”%%BTAD_InstallDir%%\TargetFolderName\%%~xnF” /Overwrite


FOR %%F IN (“PrecompiledPath\bin\*.*”) DO btstask AddResource /A:%AppName% /Type:System.BizTalk:File /Source:”%%F” /Destination:”%%BTAD_InstallDir%%\TargetFolderName\bin\%%~xnF” /Overwrite


3)       Create script that will configure virtual directory during installation when invoked. The script can use whether WMI or ADSI. Here’s an example of WMI one:


Sub ConfigureWebApplication(installPath, appPoolName, webDirName, serviceAccount, password)


    Dim iisvdirCmd, winDir, objWMI, items, item

    Const OutOfProcess = 1

    Const WaitOnReturn = True

    Const CreateIfNotExist = True

    Const WindowStyle = 0


    Set shell = CreateObject(“WScript.Shell”)

    Set environment = shell.Environment(“Process”)


    winDir = environment(“WINDIR”)


    ‘Create virtual directory

    iisvdirCmd = winDir & “\system32\iisvdir.vbs /create “ & Chr(34) & “Default Web Site” & Chr(34) & ” “ & webDirName & ” “ & _

     Chr(34) & installPath & “\” & webDirName & Chr(34)

    shell.Run iisvdirCmd, WindowStyle, WaitOnReturn


    Set objWMI = GetObject (“winmgmts:{authenticationLevel=pktPrivacy}\\.\root\microsoftiisv2”)

    Set items = objWMI.ExecQuery(“Select * From IIsWebVirtualDir Where Name = ‘W3SVC/1/ROOT/” & webDirName & “‘”)


    For Each item in items

       item.AppCreate3 OutOfProcess, appPoolName, CreateIfNotExist

       Wscript.Echo “Creating web application “ & item.Name



    Set items = objWMI.ExecQuery(“Select * From IIsWebVirtualDirSetting Where Name = ‘W3SVC/1/ROOT/” & webDirName & “‘”)


    For Each item in items

        Wscript.Echo “Configuring security for virtual directory “ & item.Name         

        item.AccessSSL = True

        item.AccessSSL128 = True

        item.AccessSSLRequireCert = True

        item.AppFriendlyName = webDirName




    ‘Set application pool identity

    Set items = objWMI.ExecQuery(“Select * from IIsApplicationPoolSetting Where Name = ‘W3SVC/apppools/” & appPoolName & “‘”)


    For Each item in items

        Wscript.Echo “Setting identity of application pool “ & item.Name

        item.WAMUserName = serviceAccount

        item.WAMUserPass = password



End Sub


This function not only creates virtual directory but completely configures web application to be used by BizTalk including setting up application pool and its identity. There are also functions to create folders, write to registry and do other useful tasks that I don’t show here.


We have to make sure our script is invoked in right context, so it can be like this:


Sub RunTasks()


      Dim installMode, path  

      installMode = environment(“BTAD_InstallMode”)


      If installMode=“Install” Then


          path = environment(“BTAD_InstallDir”)


          ‘Get other deployment parameters through dialog or config file omited




          ConfigureWebApplication(path, appPoolName, webDirName, serviceAccount, password)

      End If


End Sub


Finally, let’s add this script to the package as preprocessing (install stage):


btstask AddResource /A:%AppName% /Type:System.BizTalk:PreProcessingScript

 /Source:PreInstallScript.vbs /Overwrite


If we want to script web service publishing there’s a way to call it through object model:

WebServiceDescription desc = WebServiceDescription.LoadXml(path);
WebServiceBuilder builder = new WebServiceBuilder();
builder.WebServiceDescription = desc;

Where the path variable points to the WebServiceDescription.xml generated by Web Services publishing wizard.



1)       Run MSI on target machine and point to the desired installation directory

2)       Provide installation parameters like serviceAccount/password for IIS application pool identity. This can be done from text file or interactive form.


Now we have full control over BizTalk web project installation and can easily move application through staging deployments.