10

I've been browsing dozens of sites to help me deploy a web service to an IIS using MsDeploy. I need to create the application, modify application pool and enable protocols, and update a appSetting (that contains a connection string, don't ask me why).

I can do all of these, except applying the good Application pool.

Here's the parameters.xml file I added to the project :

<parameters>
  <parameter tags="IisApp" defaultValue="Default Web Site/MyWebService" name="IIS Web Application Name">
    <parameterEntry match="@defaultValue" scope="IisApp" kind="ProviderPath"/>
    <parameterEntry match="@defaultValue" scope="setAcl" kind="ProviderPath"/>
  </parameter>
  <parameter name="Configuration Connection String" defaultValue="Some real Connection String in there" tags="">
    <parameterEntry kind="XmlFile" scope="\\web.config$" match="/configuration/appSettings/add[@key='ConfigurationSQLConnectionString']/@value" />
  </parameter>
  <parameter name="Application Pool" defaultValue="MyOwnAppPool" description="Application pool for this site">
    <parameterEntry kind="DeploymentObjectAttribute" scope="application" match="/application/@applicationPool" />
  </parameter>
</parameters>

Here's the way I generate the package :

MsBuild MyWebService.csproj /T:Package /P:PackageLocation="c:\somewhere\package.zip" /P:IncludeAppPool=true /P:IncludeIisSettings=true

Here's the generated archive.xml file :

<sitemanifest MSDeploy.ObjectResolver.dirPath="Microsoft.Web.Deployment.DirPathObjectResolver" MSDeploy.ObjectResolver.filePath="Microsoft.Web.Deployment.FilePathObjectResolver">
  <appHostConfig path="Default Web Site/MyWebService" MSDeploy.path="2" MSDeploy.MSDeployLinkName="Child1" MSDeploy.MSDeployKeyAttributeName="path" MSDeploy.MSDeployProviderOptions="some stuff">
    <application path="/MyWebService" MSDeploy.path="2" applicationPool="DefaultAppPool" MSDeploy.applicationPool="1" enabledProtocols="http" MSDeploy.enabledProtocols="1" serviceAutoStartEnabled="false" MSDeploy.serviceAutoStartEnabled="1" serviceAutoStartProvider="" MSDeploy.serviceAutoStartProvider="1" MSDeploy.MSDeployLinkName="PathElement" MSDeploy.MSDeployKeyAttributeName="path">
      <virtualDirectoryDefaults path="" MSDeploy.path="1" physicalPath="" MSDeploy.physicalPath="9" userName="" MSDeploy.userName="1" password="" MSDeploy.password="1" logonMethod="ClearText" MSDeploy.logonMethod="1" allowSubDirConfig="true" MSDeploy.allowSubDirConfig="1" MSDeploy.MSDeployLinkName="virtualDirectoryDefaults" />
      <virtualDirectory path="/" MSDeploy.path="2" physicalPath="C:\somewhere\MyWebService" MSDeploy.physicalPath="8" userName="" MSDeploy.userName="1" password="" MSDeploy.password="1" logonMethod="ClearText" MSDeploy.logonMethod="1" allowSubDirConfig="true" MSDeploy.allowSubDirConfig="1" MSDeploy.MSDeployKeyAttributeName="path" />
    </application>
  </appHostConfig>
  <contentPath path="C:\somewhere\MyWebService\obj\Debug\Package\PackageTmp" MSDeploy.path="2" MSDeploy.MSDeployLinkName="Child2" MSDeploy.MSDeployKeyAttributeName="path" MSDeploy.MSDeployProviderOptions="some other stuff">
    <MSDeploy.dirPath path="C:\somewhere\MyWebSerivce\obj\Debug\Package\PackageTmp" MSDeploy.MSDeployLinkName="contentPath" />
  </contentPath>
  <setAcl path="C:\somewhere\MyWebService\obj\Debug\Package\PackageTmp" MSDeploy.path="2" isDest="AA==" MSDeploy.isDest.Type="Microsoft.Web.Deployment.DeploymentObjectBooleanAttributeValue" setAclUser="" MSDeploy.setAclUser="1" setAclAccess="Read" MSDeploy.setAclAccess="1" MSDeploy.MSDeployLinkName="Child3" MSDeploy.MSDeployKeyAttributeName="path" MSDeploy.MSDeployProviderOptions="still some stuff" />
  <setAcl path="C:\somewhere\MyWebService\obj\Debug\Package\PackageTmp" MSDeploy.path="2" isDest="AA==" MSDeploy.isDest.Type="Microsoft.Web.Deployment.DeploymentObjectBooleanAttributeValue" setAclUser="anonymousAuthenticationUser" MSDeploy.setAclUser="1" setAclAccess="Read" MSDeploy.setAclAccess="1" MSDeploy.MSDeployLinkName="Child4" MSDeploy.MSDeployKeyAttributeName="path" MSDeploy.MSDeployProviderOptions="final stuff I guess" />
</sitemanifest>

Here's the generated parameters.xml :

<parameters>
  <parameter name="IIS Web Application Name" defaultValue="Default Web Site/MyWebService" tags="IisApp">
    <parameterEntry kind="ProviderPath" scope="AppHostConfig" match="^Default\ Web\ Site/MyWebService$" />
    <parameterEntry kind="ProviderPath" scope="contentPath" match="^C:\\somewhere\\MyWebService\\obj\\Debug\\Package\\PackageTmp$" />
    <parameterEntry kind="ProviderPath" scope="setAcl" match="^C:\\somewhere\\MyWebService\\obj\\Debug\\Package\\PackageTmp$" />
    <parameterEntry kind="ProviderPath" scope="IisApp" match="@defaultValue" />
    <parameterEntry kind="ProviderPath" scope="setAcl" match="@defaultValue" />
  </parameter>
  <parameter name="IIS Web Application Pool Name" defaultValue="DefaultAppPool">
    <parameterEntry kind="DeploymentObjectAttribute" scope="application" match="application[@applicationPool='DefaultAppPool']/@applicationPool" />
  </parameter>
  <parameter name="IisVirtualDirectoryPhysicalPath" defaultValue="C:\somewhere\MyWebService" tags="PhysicalPath">
    <parameterEntry kind="DestinationVirtualDirectory" scope=".*" match="^C:\\somewhere\\MyWebService$" />
  </parameter>
  <parameter name="Configuration Connection String" defaultValue="Some real Connection String in there">
    <parameterEntry kind="XmlFile" scope="\\web.config$" match="/configuration/appSettings/add[@key='ConfigurationSQLConnectionString']/@value" />
  </parameter>
  <parameter name="Application Pool" description="Application pool for this site" defaultValue="MyOwnAppPool">
    <parameterEntry kind="DeploymentObjectAttribute" scope="application" match="/application/@applicationPool" />
  </parameter>
</parameters>

And finally, here's the command I launch to deploy the package :

msdeploy.exe -verb:sync -allowUntrusted -enableLink:AppPoolExtension -source:package="c:\somewhere\Package.zip" -dest:auto,computerName="https://destinationserver:8172/MsDeploy.axd?site=WebSite_Deployment",userName="destinationserver\deploymentUser",password="shouldKeepItSecret",authType="basic" -setParam:name="IIS Web Application Name",value="WebSite_Deployment/MyWebService" -setParam:name="Configuration Connection String",value="The Real Connection String" -setParam:name="Application Pool",value="FinalAppPool" -setParam:name="IIS Web Application Pool Name",value="FinalAppPool" -verbose

I get the following log :

Verbose: Parameter entry 'IIS Web Application Pool Name/1' is applicable to 'sitemanifest/appHostConfig[@path='Default Web Site/MyWebService']/application[@path='/MyWebService']' because of its scope.
Verbose: Parameter entry 'Application Pool/1' is applicable to 'sitemanifest/appHostConfig[@path='Default Web Site/MyWebService']/application[@path='/MyWebService']' because of its scope.

But finally, the application pool that is set DefaultAppPool (and not FinalAppPool as expected). I first thought that msdeploy took the default application pool value for the parameter "IIS Web Application Pool Name". but it always take DefaultAppPool. I just don't understand why.

As you can see, I'm using basic authentication with a non administrator account. I've activated Management Delegation Service on destinationServer to delegate contentPath, iisApp and setAcl to current user, and createApp and appHostConfig to WDeployConfigWriter.

The fact that I added the parameter "Application Pool" is because I found this here. But even if I keep only one of those two parameters (Application Pool and IIS Web Application Pool Name"), the 2nd one is always in the archive.xml because of the msbuild package parameter IncludeIisSettings=true. And the result is the same.

It doesn't seem to be a right issue, as long as the application pool is really set by msdeploy. It's just that it doesn't take the provided application pool.

We also have a similar problem for Enable Protocols.

Sorry for the length, but I wanted to be exhaustive.

Community
  • 1
  • 1
Jerome
  • 121
  • 6
  • You are doing all of this completely manually. Is it an option to use VSTS to do the work? You would be using msdeploy behind the scenes with much less effort and most of all ... working. – Rodrigo Werlang Mar 19 '18 at 22:23
  • What exactly are you trying to update with the app pool and why? I think knowing that would help us understand your situation better. – Dan Csharpster May 31 '18 at 23:46
  • If I am understanding correctly, you want to basically deploy an application to a server and create a site/app pool in iis that points to the application directory you just created/deployed? If that is the case this would be much easier using powershell. You can remote use powershell remoting and copy the app over, then create any app pools you need and modify them. Trying to do this via msbuild would be much harder in my opinion as it is not built for tasks like this. – Chris Bartlett May 01 '21 at 14:36

1 Answers1

0

Don't know how you're deploying, but maybe you can use a script (with postSync argument) as mentionned there:

.net WebDeploy is there any way to run command/script on the target machine after deploy

In this script you can do everything you want with appcmd:

https://docs.microsoft.com/en-us/iis/get-started/getting-started-with-iis/getting-started-with-appcmdexe

Cyril Rebreyend
  • 310
  • 2
  • 6