Azure DevOps API PropertiesCollections
I was looking at some of the Azure DevOps API documentation and noticed that some of the endpoints mention a properties object of type PropertiesCollection. Unfortunately, the details for that data structure are not particularly helpful, and I couldn’t figure out how to use it. Some pages include examples, but none that I could find included an expanded properties object.
To figure out how to use it, I created a simple .NET console application. I added references to the following NuGet packages:
- Microsoft.TeamFoundationServer.Client
- Microsoft.VisualStudio.Services.InteractiveClient
- Microsoft.VisualStudio.Services.Release.Client
using Microsoft.VisualStudio.Services.Common;
using Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.Clients;
using Microsoft.VisualStudio.Services.WebApi;
const string collectionUri = "https://dev.azure.com/organisation";
const string projectName = "MyProject";
const string pat = "YOUR-PAT-HERE";
const int releaseId = 20;
var creds = new VssBasicCredential(string.Empty, pat);
// Connect to Azure DevOps Services
var connection = new VssConnection(new Uri(collectionUri), creds);
using var client = connection.GetClient<ReleaseHttpClient>();
// Get data about a specific release
var release = await client.GetReleaseAsync(projectName, releaseId);
release.Properties.Add("Thing", "hey");
// Send the updated release back to Azure DevOps Services
var result = await client.UpdateReleaseAsync(release!, projectName, releaseId);
Console.WriteLine();This allowed me to create a property key and value, that I could then examine by querying the item (in this case a ‘classic’ release), by calling the GET endpoint. eg.
https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/releases/{releaseId}?propertyFilters=Thing&api-version=7.0Note that you need to specify the propertyFilters parameter. Otherwise the `properties“ object will not be included in the response.
And in doing that, we can see the JSON data structure!
    "properties": {
        "Thing": {
            "$type": "System.String",
            "$value": "hey"
        }
    }So, to add a property, you need to add a new key/value pair to the properties object, where the key is the name of the property, and the value is an object with two properties: $type and $value. The $type property is the type of the value, and the $value property is the value itself.
The documentation clarifies the types supported:
Values of type Byte[], Int32, Double, DateType and String preserve their type, other primitives are retuned as a String. Byte[] expected as base64 encoded string.
(I think ‘DateType’ is a typo, and should be ‘DateTime’)
Now that we know the shape of the data, I can jump back to PowerShell and use that to add a new property:
$uri = "https://vsrm.dev.azure.com/$($organisation)/$($project)/_apis/release/releases/$($releaseId)?api-version=7.0&propertyFilters=Extra"
$result = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers
if (-not ($result.properties.Extra)) {
    $result.properties | Add-Member -MemberType NoteProperty -Name "Extra" -Value @{
        "`$type" = "System.String"
        "`$value" = "haaaa"
    }
}
$body = $result | ConvertTo-Json -Depth 20
"Updating via PUT"
Invoke-RestMethod -Uri $uri -Method Put -Headers $headers -Body $body -ContentType "application/json"