MSBUILD vs. Web Deploy & Automation

So you’re here, probably on your third or fourth cup of coffee and struggling to automate the deployment of your web site(s). Don’t worry you’re not alone, I alone went threw an entire box of K-cups by the time I finally found the answer! You probably started out with using MSBUILD and the “DeployOnBuild=true” parameter for your publish profile and at first all was great! Your files were in the right location (maybe) and the site was up and running in IIS with no issues, minus the whole authentication hole you created (our secret). So you tried your mad Google skills and stumbled upon Web Deploy which looked extremely promising; but long story short, it fell short or your thinking there has to be a better way of doing this!?!?

And your right there has to be a better way! But first lets understand what MSBUILD and WebDeploy are…

MSBUILD

Microsoft Build Tools (also known as MSBuild and Microsoft Build Engine) is a build tool set for managed code as well as native C++ code and was part of .NET Framework. Visual Studio depends on MSBuild, but MSBuild does not depend on Visual Studio.

I have seen time and time again developers using devenv.exe for their automated deployment processes and for the love of all things coffee, STOP!  You need to understand that if you’re project file currently (2016) depends on devenv.exe you’ve got something wrong.  At first it may seem easier, but you’re only adding unnecessary amounts of time to your build process by starting an instance of Visual Studio, because that’s what you are doing.  Enough of my little rant back to the subject.

So MSBuild or “MIcrosoft Build Tools” is simply a build engine.  You can point it to a Solution file, a Project file, or even a custom written project file (one not auto generated when adding a new project to a solution).  It is pretty straight forward to use msbuild for example:

msbuild "C:\pathToSolution\Solution.sln"

Now when you want to use msbuild to deploy your web project the call gets a bit more invasive, but nothing we can’t handle:

mbuild "C:\pathToSolution\Solution.sln" /p:Configuation=Release /p:DeployOnBuild=true /p:PublishProfile=[WEBDEPLOYPROFILE] /p:VisualStudioVersion=[version]

Now this will probably work for 90% of you guys out there, but the other 10% maybe wondering if you can add additional configuration to this setup (e.g. AppPoolName, Remote Physical Location, Permissions, etc.).  However, this involves using Web Deploy directly.

Web Deploy

Microsoft Web Deploy is a tool to simplify the migration, management, and deployment of IIS Web servers, applications, and sites. Administrators can use command-line scripting with Web Deploy to synchronize IIS 6.0 and IIS 7.0 servers or to migrate an IIS 6.0 server to IIS 7.0.

So you read the first sentence above, like I did, and began trailing down the rabbit hole to make web deploy work with your automation tool(s) in attempts to set AppPool and Authentication to be what you need it to be.  Then at some point you realized that you’ll need a “Parameters.xml” in your project as described here.  Continuing further down the rabbit hole you then realized that you’ll need MSBUILD to create a deployment package rather than publish the website, since webdeploy.exe will be responsible for publishing the configuration to IIS.  For example:

msdeploy.exe -verb:sync -source:'C:\pathToPackageMadeByMSBUILD' -dest:auto

Which infact does publish the website.  So now it’s time to change the AppPool name as suggested here.

msdeploy.exe -verb:sync -source:'C:\pathToPackageMadeByMSBUILD' -dest:auto /P:IncludeIisSettings=true /P:IncludeAppPool=True -setParam:'AppPool'='Existing AppPool Name'

After much demise and variations of  (AppPool/ApplicationPool/Application Pool Name), and now on your fifth cup of coffee,  wondering why this doesn’t work when the documentation eludes that it should.  So you descend into the third and fourth pages of Google (it’s been a while) and eventually find nothing (maybe this article ha-ha).

Well, I’m sorry to say I did not find a reliable setup to achieve the mildly complex setup that I was aim for using MSBUILD and WebDeploy out of the box and frankly ran out of time to continue chasing the rabbit.

Happy Medium Between the Two

Seventh maybe eighth cup of coffee ready, lost count by now, and your ready to solve this problem.  Good news is there is a simple alternative to using configuration files to push out and modify changes in IIS and that is:

 Microsoft.Web.Administration Namespace

Now you might be thinking, the last thing you want to do is write some more code and maintain it.  But let me show you how simple it is to use this library:

var manager = ServerManager.OpenRemote(ServerName);

var site = manager.Sites[WebSiteName];

var application = site.Applications["/" + ApplicationName];

application.ApplicationPoolName = AppPoolName;

Microsoft.Web.Administration.Configuration config = manager.GetApplicationHostConfiguration();

Microsoft.Web.Administration.ConfigurationSection anonymousAuthenticationSection = config.GetSection("system.webServer/security/authentication/anonymousAuthentication",WebSiteName + "/" + ApplicationName);

anonymousAuthenticationSection["enabled"] = false;

manager.CommitChanges();

That’s it.  No really! Granted you have Domain/Security permissions to make such modification to IIS in general.  But that’s it.

Throwing this into a console application and parsing out the parameters, allowed me to use this command line tool to administer the website(s) in question AFTER deploying using MSBUILD.

Have any questions/comments/concerns, post them below!

Get your coffee ready and I’ll see you next time!

Leave a Reply

Your email address will not be published. Required fields are marked *