MSBuild Once, MSDeploy Many Times

Microsoft and the Visual Studio team have made it very easy to deploy an ASP.NET web application.  So easy that few take the time to look beyond its capabilities until absolutely necessary.  MSBuild initiates WebDeploy through right click Publish functionality in Visual Studio, deployment via TFS or when you manually execute the “Package” target to create an MSDeploy package.  Azure even provides publish profiles you can download and import into Visual Studio to ease deployment to an Azure website.  These are all great features and I’m not suggesting developers not use them.  Rather that they understand another option and its benefits.

To be clear, MSBuild is using MSDeploy via WebDeploy so technically you are using MSDeploy when deploying via MSBuild.  The difference is whether you initiate the deployment via MSBuild or MSDeploy.exe.

Advantages of MSDeploy over MSBuild

As a development team matures in their delivery process they will find MSBuild becomes less ideal for automating deployments.  That being said we did use it for a several years on my team at EBSCO.  Since then we have found MSDeploy meets all of our enterprise deployment needs within a lean environment on our journey to continuous delivery.  Here are a few advantages of MSDeploy:


Deploying via MSBuild typically implies that the code will also be rebuilt in addition to deployed.  Depending on your solution size it’s quite possible that the building of the code may take longer than the deployment itself.  When deploying via MSDeploy you build the package and pay that cost once then you can deploy that package many times which can significantly decrease the deployment time. 

For us this also includes unit testing time.  If you aren’t rebuilding there is no need to rerun your unit tests either. 

Some of our biggest solutions build in 5-10 minutes and run 5-10 minutes of unit tests.  The MSDeploy deployments typically take less than 5 minutes.  That’s up to 20 minutes savings for each deployment if  you only build once.

No risk of new changes

Deploying a MSDeploy package to environments (DEV, QA, STAGING, PROD) will deploy exactly the same files to each environment ensuring consistency between the environments. If you build before each deployment there is always the risk that someone may checkin in a new change that you did not intend to promote up through the environments.  This is especially risky for larger teams where many developers may be working in the same source control branch.

One less dependency

Deploying a MSDeploy package only requires MSDeploy to be installed on the machine you are deploying from.  Deploying via MSBuilld requires access to the source code and for MSBuild to be installed on the machine from which you deploy from.  In many cases this probably isn’t an issue but its not always guaranteed.  Its quite common to pass the deployment package to an operations or ALM team for deployment.

Full Power of MSDeploy

The MSBuild targets that come with Visual Studio to initiate the execution of MSDeploy for deployment is an abstraction on top of MSDeploy which only surfaces a portion of its capabilities.  Using MSDeploy directly affords you all capabilities and features of MSDeploy.  A quick example of this limitation is not being able to specify a pre/postSync command for WebDeploy from MSBuild.  You can however add a pre/postSync command if you run the package manually.

Tool Support

We recently evaluated all the top tier, enterprise-grade release management/automation tools and found MSDeploy is already integrated into most of these tools. They had tasks that could take a MSDeploy package and deploy it without any custom code, it just worked.  In addition, MSDeploy can be run from the command line for those tools that don’t yet support it.  IIS also supports deployment of MSDeploy package.via a deployment wizard.


What has your experience been?  Leave a comment and let me know.

4 thoughts on “MSBuild Once, MSDeploy Many Times”

  1. Pingback: SetParameters VIA MSBuild Commandline – dotnet Catch

  2. Pingback: Continuous Delivery… Incrementally – dotnet Catch

Leave a Reply