Azure DevOps Configuration required on new work item types (Resolved)
** Business Requirement **
Create a new iteration black log type ‘Impediment’
As part of the configuration, if a sprint board has column options other than (New | Active | Resolved | Closed), then a message of “Configuration required” will be displayed once the new work item type has been added to Azure DevOps.
Sprint board with a custom column:
Adding of the new Task type:
Sprint board with a custom column after work item type has been added:
In most cases this can easily be resolved by going to ‘Column Options’ and clicking save to update the sprint board with the correct status.
However, in our case we needed to do this across a big organization with a lot of boards, some with custom columns. As this is a disruptive action to users that would need to go to their sprint boards to update the new status.
An automated method can be used through the API. Though the documentation is vague on what the json body requirement is the engineers from Microsoft was able to provide us with the required structure.
[
{
“mappings”: [
{
“workItemType“: “Task”,
“state”: “New”
},
{
“workItemType“: “Bug”,
“state”: “New”
},
{
“state”: “New”,
“workItemType“: “Impediment”
}
],
“order”: 0,
“name”: “New”,
“id”: “”
}
]
I created the following PowerShell script to add the new work item states to sprint boards with custom added columns.
# Define parameters for the script
Param(
[string]$organisation = “AzureDevOps-Organisation-Name”,
[string]$project = “AzureDevOps-Project-Name”,
[string]$user = “email address removed for privacy reasons”,
[string]$token = “Your-PAT” # Personal Access Token
)
# Convert username and token to Base64 for Basic Authentication
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes((“{0}:{1}” -f $user,$token)))
# Define headers for the API request
$headers = @{Authorization=(“Basic {0}” -f $base64AuthInfo)}
# Define the URL for the Teams API
$TeamUrl = “https://dev.azure.com/$($organisation)/_apis/projects/$project/teams?api-version=7.1-preview.3”
# Send a GET request to the Teams API
$TeamRequest = Invoke-RestMethod -Uri $TeamUrl -Method Get -ContentType “application/json” -Headers $headers
# Loop through each team in the response
foreach ($Team in $TeamRequest.value) {
# Define the URL for the Task Board Columns API for the current team
$TaskBoardUrl = “https://dev.azure.com/$($organisation)/$project/$($Team.id)/_apis/work/taskboardcolumns?api-version=7.1-preview.1”
# Send a GET request to the Task Board Columns API
$TaskBoardResult = Invoke-RestMethod -Uri $TaskBoardUrl -Method Get -ContentType “application/json” -Headers $headers
# Loop through each column in the response
foreach ($Column in $TaskBoardResult.columns)
{
# If the column name does not match ‘New’, ‘Active’, ‘Resolved’, or ‘Closed’
if ($Column.name -notmatch ‘New|Active|Resolved|Closed’)
{
# Define an empty array for the columns
$columnsArray = @()
# Define valid states
$validStates = @(“New”, “Active”, “Closed”)
# Loop through each column in the response
$TaskBoardResult.columns | ForEach-Object {
# Create a new object for the column
$column = New-Object PSObject -Property @{
id = “”
name = $_.name
order = $_.order
mappings = $_.mappings
}
# Filter the mappings for the column
$column.mappings = $column.mappings | Where-Object { $_.workItemType -ne “Impediment” -or ($_.workItemType -eq “Impediment” -and $_.state -eq $column.name) }
# If the column name is in the valid states
if ($column.name -in $validStates) {
# Create a new mapping for the column
$newMapping = New-Object PSObject -Property @{
state = $column.name
workItemType = “Impediment”
}
# Add the new mapping to the column
$column.mappings += $newMapping
}
# Add the column to the array
$columnsArray += $column
}
# Convert the array to JSON
$jsonBody = $columnsArray | ConvertTo-Json -Depth 10
# Define the URL for the Task Board Columns API for updating
$TaskBoardUrlUpdate = “https://dev.azure.com/$($organisation)/$project/$($Team.id)/_apis/work/taskboardcolumns?api-version=7.1-preview.1”
# Send a PUT request to the Task Board Columns API to update the columns
$ResultCall = Invoke-RestMethod -Uri $TaskBoardUrlUpdate -Method PUT -Body $jsonBody -ContentType “application/json” -Headers $headers
# Print the validation message and columns from the response
$ResultCall.validationMesssage
$ResultCall.columns
}
}
}
Result after running the script:
** Business Requirement ** Create a new iteration black log type ‘Impediment’ As part of the configuration, if a sprint board has column options other than (New | Active | Resolved | Closed), then a message of “Configuration required” will be displayed once the new work item type has been added to Azure DevOps. Sprint board with a custom column:Adding of the new Task type: Sprint board with a custom column after work item type has been added:In most cases this can easily be resolved by going to ‘Column Options’ and clicking save to update the sprint board with the correct status. However, in our case we needed to do this across a big organization with a lot of boards, some with custom columns. As this is a disruptive action to users that would need to go to their sprint boards to update the new status. An automated method can be used through the API. Though the documentation is vague on what the json body requirement is the engineers from Microsoft was able to provide us with the required structure. Source: https://learn.microsoft.com/en-us/rest/api/azure/devops/work/taskboard-columns/update?view=azure-devops-rest-7.1#taskboardcolumn [ { “mappings”: [ { “workItemType”: “Task”, “state”: “New” }, { “workItemType”: “Bug”, “state”: “New” }, { “state”: “New”, “workItemType”: “Impediment” } ], “order”: 0, “name”: “New”, “id”: “” } ] I created the following PowerShell script to add the new work item states to sprint boards with custom added columns. # Define parameters for the script
Param(
[string]$organisation = “AzureDevOps-Organisation-Name”,
[string]$project = “AzureDevOps-Project-Name”,
[string]$user = “email address removed for privacy reasons”,
[string]$token = “Your-PAT” # Personal Access Token
)
# Convert username and token to Base64 for Basic Authentication
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes((“{0}:{1}” -f $user,$token)))
# Define headers for the API request
$headers = @{Authorization=(“Basic {0}” -f $base64AuthInfo)}
# Define the URL for the Teams API
$TeamUrl = “https://dev.azure.com/$($organisation)/_apis/projects/$project/teams?api-version=7.1-preview.3”
# Send a GET request to the Teams API
$TeamRequest = Invoke-RestMethod -Uri $TeamUrl -Method Get -ContentType “application/json” -Headers $headers
# Loop through each team in the response
foreach ($Team in $TeamRequest.value) {
# Define the URL for the Task Board Columns API for the current team
$TaskBoardUrl = “https://dev.azure.com/$($organisation)/$project/$($Team.id)/_apis/work/taskboardcolumns?api-version=7.1-preview.1”
# Send a GET request to the Task Board Columns API
$TaskBoardResult = Invoke-RestMethod -Uri $TaskBoardUrl -Method Get -ContentType “application/json” -Headers $headers
# Loop through each column in the response
foreach ($Column in $TaskBoardResult.columns)
{
# If the column name does not match ‘New’, ‘Active’, ‘Resolved’, or ‘Closed’
if ($Column.name -notmatch ‘New|Active|Resolved|Closed’)
{
# Define an empty array for the columns
$columnsArray = @()
# Define valid states
$validStates = @(“New”, “Active”, “Closed”)
# Loop through each column in the response
$TaskBoardResult.columns | ForEach-Object {
# Create a new object for the column
$column = New-Object PSObject -Property @{
id = “”
name = $_.name
order = $_.order
mappings = $_.mappings
}
# Filter the mappings for the column
$column.mappings = $column.mappings | Where-Object { $_.workItemType -ne “Impediment” -or ($_.workItemType -eq “Impediment” -and $_.state -eq $column.name) }
# If the column name is in the valid states
if ($column.name -in $validStates) {
# Create a new mapping for the column
$newMapping = New-Object PSObject -Property @{
state = $column.name
workItemType = “Impediment”
}
# Add the new mapping to the column
$column.mappings += $newMapping
}
# Add the column to the array
$columnsArray += $column
}
# Convert the array to JSON
$jsonBody = $columnsArray | ConvertTo-Json -Depth 10
# Define the URL for the Task Board Columns API for updating
$TaskBoardUrlUpdate = “https://dev.azure.com/$($organisation)/$project/$($Team.id)/_apis/work/taskboardcolumns?api-version=7.1-preview.1”
# Send a PUT request to the Task Board Columns API to update the columns
$ResultCall = Invoke-RestMethod -Uri $TaskBoardUrlUpdate -Method PUT -Body $jsonBody -ContentType “application/json” -Headers $headers
# Print the validation message and columns from the response
$ResultCall.validationMesssage
$ResultCall.columns
}
}
} Result after running the script: Read More