How to use the Azure CLI to clone Azure DevOps work items with variable expansion support

Azure DevOps provides several different ways to create or copy work items. In this post I dive into how to use one the newer methods: the Azure DevOps extension for Azure CLI. This toolset offers powerful automation opportunities to customize the work item clone process and add things like variable expansion.

Easier copy options

Before reaching for the Azure CLI to solve this problem, you should double check if your scenario is solved by one of these easier built-in methods:

  1. If you want to capture a template of a work item and apply that template to new or existing work items without customization, then try work item templates.
  2. If you want to clone an existing work item (and children) to make an exact copy without customization, then you can use the clone feature.
  3. If you want to define a tree of work items in Excel or csv file and have Azure DevOps bulk create them for you, then you can use this process.

Why use the Azure CLI for this?

Individual Azure CLI work item operations are going to be significantly slower than bulk API calls and some of the operations in the Azure DevOps website, but the CLI offers two distinct advantages.

First, you can call the CLI operations in a loop over a large batch of work items and it supports fully unattended scenarios.

Second, you can deeply customize the clone process by specifying which fields to clone and use variable expansions.

The following sections will explain how we can use the Azure CLI to accomplish this goal.

Step 1: Prerequisites

  1. Install the Azure CLI.
  2. Install the Azure DevOps extension for Azure CLI.
  3. Create a personal access token (PAT) for Azure DevOps that has permissions to manage work items.
  4. Test your connection by running az devops login.

Step 2: Download and review the clone script

I have uploaded an example clone script to GitHub that will perform the bulk of the work: New-ClonedWorkItemFromTemplate.ps1. Download a copy of this file (or the contents) to your computer.

This script uses az boards work-item show to fetch item details for the items we want to clone and az boards work-item create / update to create the new items and set additional fields. It also uses az boards work-item relation add to create parent/child work item links.

Step 3: Prepare work items to clone

Find a work item you want to clone. After you have reviewed the fields to make sure they are ready, you can add inline variables.

Inline variables are an optional part of the clone script– but they are a powerful way to provide customization for each cloned work item. This clone script supports variables wrapped with double-curly braces. Variable names should be word characters only (no spaces, special characters, etc).

Example inline variables that should be filled in during the clone operation.

Step 4: Call the clone script

We need to write some wrapper code to call the PowerShell clone script with our customized inputs. This example clones the example work item and uses variable expansion:

# set your Azure DevOps PAT to a process-scoped environment variable.
# for unattended scenarios, you can pull this token from a secret store/vault.
$env:AZURE_DEVOPS_EXT_PAT = "<token>"

# build a map of variable names to expand along with the values they should expand to.
$map = new-object -typename 'System.Collections.Generic.Dictionary[System.String,System.String]'
$map["ServiceName"] = "Storage Management Service"
$map["SecurityProgramManagerName"] = "George"
$map["DocumentLink"] = "https://internal-site/review-docs-v3"

# call the script
# be sure to specify the verbose flag to see logging output.
.\New-ClonedWorkItemFromTemplate.ps1 -TemplateItemId 123456 -CloneChildWorkItems $true -Verbose -VariableExpansionMap $map

If you need to clone many work items in a batch: foreach around a list of service names and call the script with a slightly modified variable expansion map for each service.

Tip: Additional customization

One way to further customize the clone process is to add or remove the work item fields that will be copied into the new work item. I included a list of common items that are cloned for each work item, which you adjust as necessary for your work items:

Warning: DevOps CLI bugs

I used Azure CLI v2.24.2 and the Azure-Devops v0.18.0 extension when writing the script. At the time of these versions, the devops extension had a couple bugs.

  1. The CLI commands failed when trying to save a work item with un-escaped quote characters in HTML fields like description and acceptance criteria. I worked around this in my example script by escaping them before sending them to the CLI commands.
  2. The –Fields option on the create/update commands only supported 1 field at a time, even though the SDK help says otherwise. The workaround for this is to submit multiple calls to update– which is terribly inefficient.

I will be filing GitHub issues for these items and will remove the workarounds in future versions of the script when the bugs are fixed. This should also help make the clone operations run a lot faster.

Leave a comment