Feb 1 2010

The trials and tribulations of using MSDeploy with PowerShell

Category: Deployment | PowerShell | MSDeployMatt @ 09:21

I can sum my experience with trying to use MSDeploy and Powershell together with a single word: hell.  MSDeploy.exe does not play nicely with PowerShell, but thanks to some help from James and a lot of trial-and-error, I’ve got it sort-of working now.  Here’s a tail of my journey.  Hopefully you, brave reader, will learn from my mistakes.  THAR BE DRAGONS HERE.

It began with the automation of deployments

This journey started from a desire to automate our deployment processes.  We have three different software applications that we host under a SaaS model, and only one of those has a deployment that even remotely qualifies as semi-automated.  Making deployment less painful typically leads to more frequent deployments and happier developers, so I set out to automate things.  I have previously used MSBuild and PowerShell to automate things, but that was several years ago, and the tools have changed.  Today, we have a new tool to help with deploying web applications: the Microsoft Web Deployment Tool, or MSDeploy. FTA:

The Web Deployment Tool simplifies the migration, management and deployment of IIS Web servers, Web applications and Web sites.

Basically, MSDeploy gives us some great functionality for remote deployments.  With it, I can deploy files, execute commands remotely, run SQL scripts, etc.  On paper, this seemed like a great tool.  Using it, I should be able to deploy applications without having to log on to the target servers at all

So, with MSDeploy installed and ready, I decided I would use PowerShell to drive things instead of MSBuild or batch scripting.  After all, PowerShell is the future of the Windows Shell. And MSDeploy is new hawtness.  So the two will surely play nice together, right?  Right?

You seek the 2.0 shell?

Before starting, I decided I would install PowerShell 2.0.  It was required for one of the tools I was using (which I’ll cover in a future post).  I was running Vista with PowerShell 1.0 installed.  So I hit up Google to find the 2.0 release:

PowerShellGoogle

Hmm, none of the top results looked like a download page for the final version.  I didn’t want a CTP, I wanted the final version.  Bing was not much better:

PowerShellBing

Bing returned a blog post indicating that the RTW version shipped, but no link in the first few results (yes, I am one of those searchers who only scans the first few hits before abandoning my query and trying a different one).  I finally found the PowerShell portal on TechNet, which did include a link to download PowerShell 2.0.  PS2 is part of the Windows Management Framework, which is intuitively* disguised as KB968929. Suggestion to Microsoft: how about making it a little less difficult to find PowerShell?

*SarcasmLevel = int.MaxValue;

There can be no alliance between PS and MSDeploy

Despite the initial frustration of finding and installing the latest PowerShell, I had high hopes that things were going to go smoother now.  I had numerous examples of how to use MSDeploy.exe from the command-line, and the documentation actually seemed pretty solid.  You can imagine my surprise when I tried running a simple example and was greeted by the following:

powershellFail

Note: The comments are mine, not MSDeploy output.  There is no MSDeploy output.  Nothing.  At all.  Until I forcibly end msdeploy, I can type whatever I want, and it just sits there quietly.

I’m not a PowerShell guru, but I don’t think that is normal behavior.  I found a handful of blog and message forum posts scattered across the web reporting similar behavior when using MSDeploy with PowerShell.  After reading the IIS blog, I started to suspect that using MSDeploy with PowerShell, at least through the command line, was actually not supportedThis really dashed my hopes:

And let us know if you want to use Web Deploy with PowerShell, we're interested in hearing about what tasks you'd like to accomplish and why!

I bet the use cases for MSDeploy with PowerShell are the same as using MSDeploy from the old CMD shell.  I’m really surprised that PowerShell is apparently not fully supported right out of the box.  I think Microsoft did realize that people might want to use the tools together. Why else would they have had PowerShell cmdlets in the early preview releases?  Unfortunately, these cmdlets were removed from the final version (see the last comment).

More digging around led me to some actual working examples of using MSDeploy with PowerShell, but it seemed a lot less elegant than running msdeploy.exe. 

An old friend comes to the rescue!

Despite this setback, I wasn’t ready to give up yet.  My initial solution was to wrap msdeploy.exe in a (very) simple batch script that I could invoke from PowerShell, but James gave me a better solution: invoke msdeploy.exe through cmd.exe directly!  I created a function to wrap the invocation, like so:

function PushToTarget([string]$server, [string]$remotePath, [string]$localPath) {
    cmd.exe /C $("msdeploy.exe -verb:sync -source:contentPath=`"{0}`" -dest:computerName=`"{1}`",contentPath=`"{2}`" -whatif" -f $localPath, $server, $remotePath )
}

Now I can use MSDeploy to sync files to my production servers.  In a future post, I’ll show you how capability fits in to our larger deployment process.

Tags:

blog comments powered by Disqus