I'm trying to put a script together that will let me loop through projects and create queries relevant to the current iteration.
I can loop through and create queries until it comes to looking at the iteration path and then it doesn't seem to like it.
When I run my script all of the other queries are created, and this one is as well, but it brings up an error when I go to look at it because it's posting that it's not in the right form. How can I get this query to loop through like the others and bring back the appropriate team in the process?
I'm assuming that somehow I've got to put project and team as variables? I tried $project as well but that just presented a similar error. Although I'm also confused about about the "" since the code doesn't like that either, and it won't even create the query when I've tried that.
$JSON27 = #'
{
"name": "Current Sprint Query", "wiql": "SELECT [System.Id], [System.WorkItemType], [System.Title], [System.AssignedTo], [System.State],[System.Tags],[Microsoft.VSTS.Scheduling.OriginalEstimate],[Microsoft.VSTS.Scheduling.CompletedWork],[System.IterationPath] FROM workitems WHERE [System.TeamProject] = #project AND [System.WorkItemType] <> '' AND [System.State] = 'Closed' AND [System.IterationPath] = #CurrentIteration('[Project]/Team') ORDER BY [System.WorkItemType]"
}
'#
$response27 = Invoke-RestMethod -Uri $url1 -Headers #{Authorization = "Basic $token"} -Method Post -Body $JSON27 -ContentType application/json
Please refer to the following script to get the project name first, and then create a query by looping through the obtained project name.
Please use #CurrentIteration('[Project]\\Team') instead of #CurrentIteration('[Project]/Team') or #CurrentIteration('[Project]\Team')
$token = "your PAT"
$url="https://dev.azure.com/org name/_apis/projects?api-version=6.0"
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($token)"))
$response = Invoke-RestMethod -Uri $url -Headers #{Authorization = "Basic $token"} -Method Get -ContentType application/json
echo $url
foreach ($project in $response.value.name){
$url3="https://dev.azure.com/org name/$($project)/_apis/wit/queries/My Queries?api-version=6.1-preview.2"
echo $url1
$body = "{
`"name`": `"query name`",
`"wiql`": `"Select [System.Id], [System.State] From WorkItems where [System.IterationPath] = #CurrentIteration('[$project]\\$project Team') `"
}"
echo $body
$response3 = Invoke-RestMethod -Uri $url3 -Headers #{Authorization = "Basic $token"} -Method Post -Body $body -ContentType application/json
echo $response3
}
Summarizing the discussion in comments as an answer below:
So, as the error message calls out, I think the issue is that you have #CurrentIteration('[Project]/Team') in your query instead of #CurrentIteration('[Project]\Team').
Your query should be this instead:
$JSON27 = #'
{
"name": "Current Sprint Query", "wiql": "SELECT [System.Id], [System.WorkItemType], [System.Title], [System.AssignedTo], [System.State],[System.Tags],[Microsoft.VSTS.Scheduling.OriginalEstimate],[Microsoft.VSTS.Scheduling.CompletedWork],[System.IterationPath] FROM workitems WHERE [System.TeamProject] = #project AND [System.WorkItemType] <> '' AND [System.State] = 'Closed' AND [System.IterationPath] = #CurrentIteration('[Project]\Team') ORDER BY [System.WorkItemType]"
}
'#
EDIT:
By default, shared queries and new queries are scoped to the current project. For querying across multiple projects, you can add the TeamProject field to filter to a select number of projects as:
..
AND [System.TeamProject] IN ('Project 1', 'Project 2', 'Project 3')
However, using the #CurrentIteration macro would need you to select a Team and may not work across Projects and Teams. Check this idea on Developer Community for more details.
Related
Hello I have 145 releases
And I have to do an equal action for everyone for example add a certain variable and edit a certain line.
Is there a way to control everyone with a script?
I checked for a template, but it creates the release from 0 and does not edit it.
Can a script in PS or Python be a solution? I did not find any information on Google about it, other than an export release template.
Azure devops release edit bulk 110
You could use the REST API Definitions - Update to update the release pipeline:
PUT https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/definitions/{DefinitionsId}?api-version=6.0
And if we want to batch modify the release pipeline, we need to get each ID of the release pipeline with REST API Definitions - List:
GET https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/definitions?api-version=6.0
Then we could iterate through each Rlease ID obtained.
I provide a rough code for your better reading:
$connectionToken="PAT"
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))
$ReleasePipelineUrl = "https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/definitions?api-version=6.0"
Write-Host "URL: $ReleasePipelineUrl"
$ReleasePipelines = (Invoke-RestMethod -Uri $PipelineUrl -Method Get -UseDefaultCredential -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)})
$ReleasePipelinesId = $ReleasePipelines.value.id
Write-Host "ReleasePipelinesId = $ReleasePipelinesId"
ForEach ($Pt in $ReleasePipelinesId)
{
$baseUrl = "https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/definitions/$($Pt)?api-version=6.0"
$pipeline = (Invoke-RestMethod -Uri $baseUrl -Method Get -UseDefaultCredential -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)})
Write-Host "URL: $baseUrl"
$pipeline.variables.TestValue.value = "$buildNumber"
####****************** update the modified object **************************
$json = #($pipeline) | ConvertTo-Json -Depth 99
Write-Host "URL: $json "
$updatedef = Invoke-RestMethod -Uri $url -Method Put -Body $json -ContentType "application/json" -Headers #{Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"}
write-host "=========================================================="
Write-host "The value of Varialbe 'TestValue' is updated to" $updatedef.variables.TestValue.value
}
I am new to powershell, and I am trying to create a simple script that will allow me to turn on several Azure VMs using the invoke-restmethod.
My code works when instead of using a variable I directly write the VM name into the url, but I want to use a variable, since eventually this must work for more than one VM.
Relevant part of code:
$body = #{
"$virtualMachines" = "VM1"
} | ConvertTo=Json
$url= "https://management.azure.com/subscriptions/mySubscriptionId/resourceGroups/myResourceGroupName/providers/Microsoft.DevTestLab/labs/myLabName/virtualmachines/" + $virtualMachines + "/start?api-version=2018-09-15"
$response = Invoke-RestMethod -uri $url -Method 'POST' -Headers $headers -Body $body
$response | ConvertTo-Json
If you had a number of VMs, you could put them all into a PowerShell variable like this, an array of strings.
$VMs = "myVm1", "myVm2", "myVm3"
PowerShell has a number of flow control statements, the one you want to use is ForEach, which will step through an array one at a time. We just modify the way you're setting up the URL to be friendlier and easier to read and this should work just fine.
$baseUrl = "https://management.azure.com/subscriptions/mySubscriptionId/resourceGroups/myResourceGroupName/providers/Microsoft.DevTestLab/labs/myLabName/virtualmachines/"
ForEach ($vm in $VMs){
$url = $baseurl + $vm + "/start?api-version=2018-09-15"
Write-host "About to start [$Vm]"
$response = Invoke-RestMethod -uri $url -Method 'POST' -Headers $headers
$response | ConvertTo-Json
}
I checked the API documentation for the start? REST API endpoint, and it doesn't look like you need the -Body parameter for this endpoint.
I'm trying to create the same queries across several projects. I feel like I'm almost there, but can't come up with the right 'thing' to create more than one query. I've tried "," ";" "AND" - and have managed to get it to create one but never both.
Could someone assist?? I've put down a quick example snippet of the type of thing I'm trying (which is why the fields are the same). If I can get that right, I'll use it for real with all the different queries I have (there's quite a few!)
{ $url1="https://dev.azure.com/[ORGANISATION]/$($project)/_apis/wit/queries/Shared Queries?api-version=6.0"
$JSON = #'
{
"name": "All User Stories JW6", "wiql": "SELECT [System.Id], [System.WorkItemType], [System.Title], [System.AssignedTo], [System.State],[System.Tags],[Microsoft.VSTS.Scheduling.OriginalEstimate],[Microsoft.VSTS.Scheduling.CompletedWork] FROM workitems WHERE [System.WorkItemType] = 'User Story' AND [System.State] = 'Active' ORDER BY [System.WorkItemType]",
"name": "All User Stories JW7", "wiql": "SELECT [System.Id], [System.WorkItemType], [System.Title], [System.AssignedTo], [System.State],[System.Tags],[Microsoft.VSTS.Scheduling.OriginalEstimate],[Microsoft.VSTS.Scheduling.CompletedWork] FROM workitems WHERE [System.WorkItemType] = 'User Story' AND [System.State] = 'Active' ORDER BY [System.WorkItemType]"
}
'#
Create several queries across multiple projects in Azure DevOps
I am afraid we could not set duplicate Keys in JSON body.
That because the names in json object SHOULD be unique, check the state in RFC-7159:
The current standard for JSON published by the Internet Engineering
Task Force (IETF), states "The names within an object SHOULD be
unique".
I use the body in the postman, I got the same warning:
If we use the duplicate Keys in JSON body, most popular parsers may take only the last value present in the object for a particular key and ignore the previous ones.
In your sample, only query All User Stories JW7 will be created.
To resolve this issue, we have to create a another body $JSON2, and send another request:
$JSON2 = #'
{
"name": "All User Stories JW7", "wiql": "SELECT [System.Id], [System.WorkItemType], [System.Title], [System.AssignedTo], [System.State],[System.Tags],[Microsoft.VSTS.Scheduling.OriginalEstimate],[Microsoft.VSTS.Scheduling.CompletedWork] FROM workitems WHERE [System.WorkItemType] = 'User Story' AND [System.State] = 'Active' ORDER BY [System.WorkItemType]"
}
'#
$CreateQuery1= Invoke-RestMethod -Uri $url -headers $headers -Method Post -ContentType "application/json" -Body $Json1
$CreateQuery2= Invoke-RestMethod -Uri $url -headers $headers -Method Post -ContentType "application/json" -Body $Json2
I'm running a script:
# Variables
$organization = "****"
$project = "****"
$repositoryId = "****"
$pullRequestId = $env:BUILD_PULLREQUEST_ID
$pat = "Bearer $env:System_AccessToken"
$featureReleaseUrl = "http://" + $env:prSourceBranchName + ".azurewebsites.net"
$body = #"
{
"comments": [
{
"content": "Link naar feature release $featureReleaseUrl"
}
]
}
"#
$createThreadInPRUrl = "https://dev.azure.com/$organization/$project/_apis/git/repositories/$repositoryId/pullRequests/$pullRequestId/threads?api-version=5.0"
if ($pullRequestId) {
Invoke-RestMethod -Uri $createThreadInPRUrl -Headers #{Authorization = $pat} -Body $body -Method Post -ContentType 'application/json'
}
When it runs it returns a:
##[error]The remote server returned an error: (403) Forbidden.
I've created a Personal Access Tokens in my personal settings.
I've also created this script:
# Variables
$organization = "****"
$project = "****"
$buildId = $****
$pat = "Bearer $env:System_AccessToken"
if (!$env:Build_PullRequest_SourceBranchName) {
$retrieveSourceBranchFromBuildURL = "https://dev.azure.com/$organization/$project/_apis/build/builds/$buildId" + "?api-version=5.0"
$buildInformation = Invoke-RestMethod -Uri $retrieveSourceBranchFromBuildURL -Headers #{Authorization = $pat } -Method Get -ContentType 'application/json'
$SourceBranchFromBuild = $buildInformation.sourceBranch.split('/')[-1]
Write-Host "### no Build PullRequest SourceBranchName available ###"
Write-Host "##vso[task.setvariable variable=prSourceBranchName;]"$SourceBranchFromBuild
}
And this runs fine. The difference between the first and second script is that the first is a POST and the second a GET. But they both use the $pat token.
Even though the token you used is System.AccessToken, if you don't have access permission of Pull Request, you will also could not operate it.
Go Project Setting--> Repositories--> Repository you want to access, locate your account or the group you are in. Check the permission state of Contribute to pull requests.
You must have this Contribute to pull requests permission allowed, so that you can add the comment to PR.
Using REST APIs of VSTS in PowerShell, I wanted to create a report on my VSTS Team Project which consists of the details of the Work Item Linking relationships of all workitems under particular "Iteration Path" and "Area Path".
Ex: Epics→Features→UserStories. Since there are parent/child relationships between Epics & Features and also between Features & UserStories.
So the input would be Iteration Path and Area Path, and the corresponding output would be a report (.csv or .xls) which has all the details of these workitems and their relationships.
Could someone let me know on how to achieve this using REST APIs in PowerShell?
I wrote the code for getting the hierarchical workitems in a Team Project but need to modify to filter the the list based on a given Iteration and Area paths.
Also when executing the below code, the string comparison in the query(due to presence of '') is returning an error in the power-shell.
Error: Invoke-RestMethod : {"count":1,"value":{"Message":"After parsing a value an unexpected character was encountered: G.
Path 'query', line 1, position 163.\r\n"}}
$vstsAccount = "xxxx"
$projectName = "xxxx"
$user = "xxxx"
$token = "xxxx"
# Base64-encodes the Personal Access Token (PAT) appropriately
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))
# Construct the REST URL to obtain Build ID
$uri = "https://$($vstsAccount).visualstudio.com/$($projectName)/_apis/wit/wiql?api-version=1.0"
$body = "{'query': 'Select [System.Id], [System.WorkItemType], [System.Title], [System.AssignedTo], [System.State] From WorkItemLinks WHERE
((Source.[System.TeamProject] = '$projectName' and Source.[System.State] <> 'Removed') and (Source.[System.WorkItemType] = 'Epic') and
([System.Links.LinkType] = 'System.LinkTypes.Hierarchy-Forward') and (Target.[System.WorkItemType] = 'UserStory') mode(Recursive)'}"
# Invoke the REST call and capture the results (notice this uses the POST method)
$result = Invoke-RestMethod -Uri $uri -Method Post -ContentType "application/json" -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)} -Body $body
Modify part of your code like this:
$query = "Select
[System.Id],
[System.WorkItemType],
[System.Title],
[System.AssignedTo],
[System.State]
From WorkItemLinks
WHERE (
Source.[System.TeamProject] = '$projectName'
AND Source.[System.State] <> 'Removed'
) AND (
Source.[System.WorkItemType] = 'Epic')
AND ([System.Links.LinkType] = 'System.LinkTypes.Hierarchy-Forward'
) AND (Target.[System.WorkItemType] = 'UserStory') mode (Recursive)
"
$body = #{query=$query} | ConvertTo-Json
$result = Invoke-RestMethod -Uri $uri -Method Post -ContentType "application/json" -Headers #{Authorization=("Basic $base64AuthInfo")} -Body $body