0
votes

I'm trying to figure out how to modify the parameter values in a test case in Azure Devops (ADO) using powershell. Unfortunately, the ADO REST API documentation doesn't go into much detail on that subject, so I've mostly been doing it through trial and error.

This is my code so far:

$PAT = "xxxxxxxxxxxxxxxxxxxxxxxx"
$Org = "MyOrganization"
$Project = "MyProject"
$ADOHeader = @{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($PAT)")) }
$BaseURI = "https://dev.azure.com/$($Org)/$($Project)/"
$Endpoint = $BaseURI + "_apis/wit/workitems/224572?api-version=6.0"

$result = Invoke-RestMethod -Uri $Endpoint -Method get -Headers $ADOHeader
$fields = $result.fields
[XML]$table = $fields.'Microsoft.VSTS.TCM.LocalDataSource'

$table.NewDataSet.Table1[0].Parameter1 = "209623"

$update = @{
    "op" = "add"
    "path" = "/fields/Microsoft.VSTS.TCM.LocalDataSource"
    "value" = $table.OuterXml
    } | ConvertTo-Json -Depth 5

$patch = Invoke-RestMethod -Uri $Endpoint -Method patch -Headers $ADOHeader -Body $update -ContentType "application/json-patch+json"

When I perform the get request in order to retrieve the test case data, the parameters are in the Microsoft.VSTS.TCM.LocalDataSource field as an XML object. I thought that since it's sent to me in XML format, then that's the format it needs to be sent back, but that doesn't appear to be the case because I keep receiving this error: "You must pass a valid patch document in the body of the request." I can't seem to track down the format that the patch document needs to be in.

Any help would be appreciated. Thank you!

edit - I added the c# tag incase someone has experience working with test cases in Azure Devops REST API through a c# project and knows how the patch document needs to be formatted.

Final Solution

Here is my modified code using Bright Ran-MSFT's recommendation

$PAT = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
$Org = "MyOrganization"
$Project = "MyProject"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "", $PAT)))

$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", ("Basic {0}" -f $base64AuthInfo))
$headers.Add("Content-Type", "application/json-patch+json")

$BaseURI = "https://dev.azure.com/$($Org)/$($Project)/"
$Endpoint = $BaseURI + "_apis/wit/workitems/{id}?api-version=6.1-preview.3"

$result = Invoke-RestMethod -Uri $Endpoint -Method get -Headers $headers
$table = $result.fields.'Microsoft.VSTS.TCM.LocalDataSource'


$table.NewDataSet.Table1[0].Parameter1 = "123456"

$pBody = $table.OuterXml.Replace('"','''')

$body = "[
    {
      `"op`": `"replace`",
      `"path`": `"/fields/Microsoft.VSTS.TCM.LocalDataSource`",
      `"value`": `"$pBody`"
    }
  ]"

$put = Invoke-RestMethod -Uri $Endpoint -Method patch -Headers $headers -Body $body
1

1 Answers

0
votes

You can try like as this:

  1. Execute the endpoint "Work Items - Get Work Item", from the response body you can see the information of the parameters is returned as a XML format string for the property '/fields/Microsoft.VSTS.TCM.LocalDataSource'. Copy the XML format string.

    GET https://dev.azure.com/{organization}/{project}/_apis/wit/workitems/{id}?$expand=all&api-version=6.1-preview.3
    

    enter image description here

  2. Use the endpoint "Work Items - Update" to change the values of the parameters.

    • Request URI

      PATCH https://dev.azure.com/{organization}/{project}/_apis/wit/workitems/{id}?api-version=6.1-preview.3
      
    • Required header

      Content-Type: application/json-patch+json
      
    • Request Body

      [
        {
          "op": "replace",
          "path": "/fields/Microsoft.VSTS.TCM.LocalDataSource",
          "value": "Paste the XML format string here and change parameter values to the new"
        }
      ]
      

[UPDATE]

According to my further investigations, I think the reason may be that some escaped characters need to be considered during converting the value between the XML type and the string type.

To avoid the problems may be caused by the conversion between the XML type and the string type, you can try directly updating the parameters from the response body of the GET request, without converting the value to XML type.

Here is an example PowerShell script as reference.

$pat = "personal access token"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "", $pat)))

$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", ("Basic {0}" -f $base64AuthInfo))
$headers.Add("Content-Type", "application/json-patch+json")

$uri_GET = "https://dev.azure.com/{organization}/{project}/_apis/wit/workitems/{id}?`$expand=all&api-version=6.1-preview.3"

$response = Invoke-RestMethod -Uri $uri_GET -Headers $headers -Method GET

# Replace the values of the parameters 'param01' and 'param02' from the XML format string
$str_table = [Regex]::Replace($response.fields.'Microsoft.VSTS.TCM.LocalDataSource', "<param01>.*</param01>", "<param01>112233</param01>")
$str_table = [Regex]::Replace($str_table, "<param02>.*</param02>", "<param02>445566</param02>")

$uri_PATCH = "https://dev.azure.com/{organization}/{project}/_apis/wit/workitems/{id}?api-version=6.1-preview.3"

$body = "[
    {
      `"op`": `"replace`",
      `"path`": `"/fields/Microsoft.VSTS.TCM.LocalDataSource`",
      `"value`": `"$str_table`"
    }
  ]"

Invoke-RestMethod -Uri $uri_PATCH -Headers $headers -Body $body -Method PATCH