Creating custom VSTS build/release tasks

VSTS is great in that not only do they provide a bunch of very useful tasks out of the box, but people can also create their own and contribute them to a marketplace.  However, documentation on creating and developing custom tasks is currently thin and what is there is out of date or doesn’t answer some obvious questions.

Links / Dependencies

NodeJs (you must install this as NPM is used to pull down a VSTS client for uploading your task)
TFS Extensions Command Line Utility (tfx-cli, the VSTS client)

Preparing your environment

  1. Install NodeJs. Make sure you select the option to install it in PATH.
  2. Open a command line (any will work), and run the following command:
    > npm install -g tfx-cli

    This will install the VSTS client.

  3. Using a command line, change directory to where you want to store the task files locally

    > cd "C:\VSTS tasks\"
  4. Using a command line, run the following commands:
    > tfx
    > tfx build tasks create

    This will result in being prompted for the following information:

    Task Name – The name of the task.  This is the programmatic name of the task, so no whitespaces.
    Friendly Task Name – The friendly name of the task.  This what people will see when selecting the task.  Whitespace is permitted.
    Task Description – Describe your task in a sentence or two.
    Task Author – Your or your company’s name.

    Once you have entered that information, the utility will create a folder with whatever Task Name you entered with a task.json file.

Task anatomy

A task is comprised of a couple files:

  1. task.json – This file describes the task and allows you to inform VSTS of what inputs to show in the web interface.  It also defines if the task is a build, release or both task, the default task title, databinding, etc.  It also points to the file that will execute whatever work the task needs to perform.
  2. icon.png – This will not be created for you, but you can insert a 32px by 32px icon named icon.png to display in the task list in VSTS.
  3. TS or PS file – This will do the work the task should perform.


The anatomy of a task.json file can be found here.

task.json is not only the metadata of the task, but can also do some pretty powerful things, such as linking datasources to fields.  Examples of this can be found in the AzureRmWebAppDeployment task in which datasources are used to look up resource groups, subscriptions, web apps, slots, etc.  Viewing the source code for that task.json can help point you in the correct direction for implementing such a datasource.  As of this writing, it does not appear that custom datasources are not useable.

Setting up your task to work with Powershell

One caveat to using PS is you have to include some additional file in your task.  The task engine will automatically look for these files when the task goes to execute (why it’s not included during task creation is behind anyone’s comprehension).  The steps to include these files are as following (directions were found here):

  1. Open Powershell
  2. Run
    Save-Module -Name VstsTaskSdk -Path .\

    This might prompt you to install nuget, as behind the scenes it’s a nuget being pulled down.

  3. Update the execution configuration in your task.json to use Powershell3
        "execution": {
            "PowerShell3": {
                "target": "$(currentDirectory)\\MyTask.ps1",
                "argumentFormat": "",
                "workingDirectory": "$(currentDirectory)"
  4. Package the SDK with the task
    |   MyTask.ps1
    │   task.json

    Be sure to copy all the files in the SDK.

Getting the task input values in your PS file

While a lot of tutorials will say that using the PS param keyword and matching the input names to your param variables will pass the data in, I didn’t find that to work.  Instead, using the SDK you imported, you can grab input data this way:

$variable1 = Get-VstsInput -Name "variable1";

Where -Name is the programmatic name of the input.

Getting environment variable values

To retrieve environmental variables, you would convert the variable name’s ‘.’ to ‘_’ and then prefix it with $Env:.  For example, the following retrieves the release environment name:

$environmentName = $Env:RELEASE_ENVIRONMENTNAME;

Deploying your task

Every time you deploy your task, make sure you change the version number, otherwise the definition may not see the change and won’t include your changes.  To deploy, run the following command:

tfx build tasks upload --task.path "<path to your task's root folder>"

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Create a website or blog at

Up ↑

%d bloggers like this: