Tokenising Release Management in VSTS

Yesterday I spent a bit of time working with the new Release Management components on VSTS ( - essentially Microsoft's hosted TFS implementation) in the knowledge that this will be (almost) what appears in the TFS 2015 Update 2 builds.

The first thing I noticed was the distinct lack of support for pushing environment configuration into the SetParameters files used by WebDeploy; essentially all you could change was the connection string if you were willing to try and work out the advanced parameters to pass in. This just wouldn't be enough for most of the projects I was involved in, and I found it pretty bizarre considering the way the existing on-premise Release Management works with WebDeploy.

So I extended the Azure Web Deploy action to add in tokenisation. And heres how.

First step - extend the Azure PowerShell Publish-AzureWebsiteProject.

Ultimately speaking, this is what VSTS is firing off in the background and so this is where we need to start.

A quick branch of the GitHub code for Azure-Powershell (thank you Microsoft for making this all Open Source!), and a dive into the code in src/ServiceManagement/Services/Commands/Websites/PublishAzureWebsiteProject.cs. It's pretty clear that this function would need to accept an additional set of arguments, and then carry out the tokenisation (i.e. replacement) in the SetParameters.xml file.

With that done, a compile and overwrite the existing copy on my machine (in %ProgramFiles%\Microsoft SDKs\Azure\PowerShell) and then a test in an Azure PowerShell and time to move on.

Second step - clone the existing VSTS Deploy to Azure Website task

Ironically, this step took more work. 

In order to create a task for Build or Release pipelines on VSTS, you need to get you environment setup first. Microsoft have gone down the cross-platform route here, which makes a lot of sense given the direction VSTS is taking.

Download and install NodeJS for your platform (

Install the tfx-cli tooling using npm (

First step is to authenticate with the service; you do this by issuing a tfx login command. You will be prompted for you VSTS url as well as your personal access token.

After you have done that, you need to create a task: issue a tfx build tasks create and you will be prompted for:

TFS Cross Platform Command Line Interface v0.3.9
Copyright Microsoft Corporation
> Task Name: Antask
> Friendly Task Name: Testing
> Task Description: Testing
> Task Author: Andy
created task @ C:\Users\Andy\Antask
id   : ----
name: Antask
A temporary task icon was created.  Replace with a 32x32 png with transparencies
At this point the task folder will contain a number of template files for you to modify. I grabbed the code for the existing actions from the Microsoft VSO Agents Task GitHub page and copied the contents of the existing action (under Tasks/AzureWebPowerShellDeployment/) while retaining the existing copy of task.json from my template folder; this is the file you will need to merge some code into in order to be able import the action again. The task.json file from the Microsoft GitHub repo is pretty complete - bit things like the name, task id etc need to be changed to that of the task.json template file. Do this and drop the merged file into your task folder.
Add a new parameter onto the task by adding the block into the inputs section; something like:

      "name": "Tokens",

      "type": "string",

      "label": "Tokens to replace",

      "defaultValue": "",

      "helpMarkDown": "Tokens to replace in the SetParameters.xml as used by Web Deploy.",

      "required": false


Then its the PowerShell script that needs modified; the new parameter needs to be added to the param block, then the actual call to $azureCommandArguments. And thats essentially all the modifications needed.

Uploading the action is a simple matter of issuing a tfx build tasks upload --task-path ./ANTest

And that is it!

I have repo's on GitHub for modified versions of both azure-powershell and vso-agent-tasks; hopefully I can get a couple of Pull Requests accepted with some work!