0
votes

I'm trying to add Iterations and Calendar holidays to my Azure DevOps project and can't figure it out.

Using Azure DevOps CLI and some PowerShell script code found here then running it, the window immediately closes. Nothing is created in any project and no console writing happens:

Param
(
    [string]$PAT = [my PAT],
    [string]$Organization = [my organization],
    [string]$Project = 'DevTeam',
    [string]$TeamName = 'DevTeam Team',
    [DateTime]$StartDate = Get-Date,
    [int]$NumberOfSprints = 18
)

echo $PAT | az devops login --org $Organization

Write-Host '===Configuring connection to organization and Team Project'
az devops configure --defaults organization=$Organization project=$Project

For ($i=1; $i -le $NumberOfSprints; $i++) 
{
    $StartDateIteration = $StartDate.AddDays(($i - 1) * 14)
    $FinishDateIteration = $StartDateIteration.AddDays(20)
    $Sprint = $StartDateIteration + '-' + $FinishDateIteration
    $createIteration = az boards iteration project create --name $Sprint --start-date $StartDateIteration --finish-date $FinishDateIteration --org $Organization --project $Project | ConvertFrom-Json
    $addIteration = az boards iteration team add --id $createIteration.Identifier --team $TeamName --org $Organization --project $Project | ConvertFrom-Json
    Write-Host $addIteration.name 'created on path'$addIteration.path
}

So I found this that uses the REST API. I wrote something quickly in Postman for the REST API, but that is also returning an error:

Pre-request script:

var occurences = 18;
var start_date = "11/11/2020";
for(i=1; i <= occurences; i++){
    var repeat_every = 21*i; //repeat every number of days/weeks/months
    var first = new Date(start_date);
    first.setDate( first.getDate() + repeat_every );
    var last = new Date(first.setDate(first.getDate() - 1));
    var name = first.toDateString() + "-" + last.toDateString();
    pm.environment.set("first", first);
    pm.environment.set("last", last);
    pm.environment.set("name", name);
};

JSON POST body to "dev.azure.com/[my organization]/DevTeam/_apis/work/teamsettings/iterations?api-version=6.0"

{
  "id": [my identifier from "GET dev.azure.com/[my organization]/DevTeam/_apis/wit/classificationnodes/iterations?api-version=6.0],
  "name": {{name}},
  "path": "DevTeam\\Iteration",
  "attributes": {
    "startDate": {{first}},
    "finishDate": {{last}}
  }
}

Error:

{
    "$id": "1",
    "innerException": null,
    "message": "TF400898: An Internal Error Occurred. Activity Id: bbe88905-2083-47e2-9b2c-d87be87c4adb.",
    "typeName": "Newtonsoft.Json.JsonReaderException, Newtonsoft.Json",
    "typeKey": "JsonReaderException",
    "errorCode": 0,
    "eventId": 0
}
  1. How can I make either of these run successfully?
  2. Will this automatically add iterations on the Calendar? The idea is to consolidate calendars and have DevOps track our work hours and time off so we can use that in sprint planning.

Thanks.

1
Not a solution for you, but a lot of the screen UI leverage the same API. You might try just manually adding one to mimic what you are scripting. Then inspect the network traffic using the browser debugger. - Matt
Hi @aplane1290. Is there any update about this ticket? Feel free to let me know if the answer could give you some help. Just a remind of this. - Kevin Lu-MSFT

1 Answers

2
votes

I would like to share the Rest API method.

This Rest API : Iterations - Post Team Iteration is only used to add the Iteration to team.

If you need to create or change an existing iteration, you need to combine the following two APIs:

Create New Iteration: Classification Nodes - Create Or Update

Update Existing Iteration: Classification Nodes - Update

Here are the PowerShell script examples:

Create new iteration and add the iteration to the team:

$token = "PAT"

$url="https://dev.azure.com/{OrganizationName}/{ProjectName}/_apis/wit/classificationnodes/Iterations?api-version=5.0"

$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($token)"))

$JSON = @'
{
  "name": "kevin5 Iteration",
  "attributes": {
    "startDate": "2014-10-27T00:00:00Z",
    "finishDate": "2014-10-31T00:00:00Z"
  }
}
'@

$response = Invoke-RestMethod -Uri $url -Headers @{Authorization = "Basic $token"} -Method Post -Body $JSON -ContentType application/json

$IterationId = $response.identifier

echo $IterationId

$url2 = "https://dev.azure.com/{OrganizationName}/{ProjectName}/{TeamName}/_apis/work/teamsettings/iterations?api-version=6.0"

$body = "{                
      `"id`": `"$IterationId`"
          }"

$response = Invoke-RestMethod -Uri $url2 -Headers @{Authorization = "Basic $token"} -Method Post -Body $body -ContentType application/json

Update the existing Iteration and add the iteration to the team:

$token = "PAT"

$url="https://dev.azure.com/{OrganizationName}/{ProjectName}/_apis/wit/classificationnodes/iterations/{IterationName}?api-version=5.0"

$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($token)"))

$JSON = @'
{
  "name": "Edit Iteration",
  "attributes": {
    "startDate": "2014-10-27T00:00:00Z",
    "finishDate": "2014-10-31T00:00:00Z"
  }
}
'@

$response = Invoke-RestMethod -Uri $url -Headers @{Authorization = "Basic $token"} -Method PATCH -Body $JSON -ContentType application/json

$IterationId = $response.identifier

echo $IterationId

$url2 = "https://dev.azure.com/{OrganizationName}/{ProjectName}/{TeamName}/_apis/work/teamsettings/iterations?api-version=6.0"

$body = "{                
      `"id`": `"$IterationId`"
          }"

$response = Invoke-RestMethod -Uri $url2 -Headers @{Authorization = "Basic $token"} -Method Post -Body $body -ContentType application/json