Please find below request body I created in powershell with Patch method to create a bug in TFS. But not able to create a bug and gettign message that "TF401320: Rule Error for field Found In. Error code: Required, HasValues, InvalidEmpty.","typeName"..... I also attached error code here.
# Base64-encodes the Personal Access Token (PAT) appropriately
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$pass)))
function CreateJsonBody
{
$value = #"
[
{
"op": "add",
"path": "/fields/System.Title",
"value": "TestBug"
},
{
"op": "add",
"path": "/fields/Microsoft.VSTS.TCM.ReproSteps",
"value": "Our authorization logic needs to allow for users"
},
{
"op": "add",
"path": "/fields/Microsoft.VSTS.Common.Priority",
"value": "1"
},
{
"op": "add",
"path": "/fields/Microsoft.VSTS.Common.Severity",
"value": "2 - High"
}
]
"#
return $value
}
$json = CreateJsonBody
$uri = "http://xxx-xxxxx-006:8080/tfs/xxx/xxxxx/_apis/wit/workItems/"+"$"+"bug/?api-version=2.0"
Write-Host $uri
$result = Invoke-RestMethod -Uri $uri -Method Patch -Body $json -Credential
$credential -ContentType "application/json-patch+json" -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)}
But not getting response.
Below error is getting
{
"$id": "1",
"innerException": null,
"message": "TF401320: Rule Error for field Found In. Error code: Required, HasValues, InvalidEmpty.",
"typeName": "Microsoft.TeamFoundation.WorkItemTracking.Server.RuleValidationException, Microsoft.TeamFoundation.WorkItemTracking.Server, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
"typeKey": "RuleValidationException",
"errorCode": 600171,
"eventId": 3200
}
Please help me. I already write code to create bugs for another account but not able to do here.
Related
How i can Associate Work Item With Current Build and attach file json to work item using powershell ? I use Azure Devops Service and i have this script:
$connectionToken="<my_token>"
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))
$url= 'https://dev.azure.com/{organization}/{project_name}/_apis/wit/workitems/$Task?api-version=6.0'
$body=#"
[
{
"op": "add",
"path": "/fields/System.WorkItemType",
"value": "Risk"
},
{
"op": "add",
"path": "/fields/System.Title",
"value": "Test"
},
{
"op": "add",
"path": "/fields/System.Tags",
"value": "test"
},
{
"op": "add",
"path": "/fields/System.Description",
"value": "test"
},
{
"op": "add",
"path": "/fields/Mitigation",
"value": "test"
},
{
"op": "add",
"path": "/fields/Risk",
"value": "1 - High"
},
{
"op": "add",
"path": "/fields/Microsoft.VSTS.Build.IntegrationBuild",
"value": `"{value}`"}]"
}
]
"#
Write-Host "$url"
$response= Invoke-RestMethod -Uri $url -ContentType "application/json-patch+json" -Body $body -headers #{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method POST
But link for associate with current build not work, and i cant find what i need to add to attach json file to work item from my Azure Pipeline
To attach a file, you have to upload the file (Upload a text file) and then add the link to your work item (Add an attachment): Attach a file and create new workitem
Microsoft.VSTS.Build.IntegrationBuild is just a field without any links. You have to add ArtifactLink link with Integrated in build type: Add build link to work item using REST API
Using PowerShell I am attempting to remove a user from groupType projectContributor so I can move him to the Project Team. I can accomplish the add to the Project Team however I have tried everything I can to remove this users entitlement using a PATCH without success. FYI to avoid comments, OrgUrl, projectId and userId are being passed.
$b= #"
[
{
"op": "remove",
"path": "/projectEntitlements",
"value": {
"projectRef": {
"id": "$projectID"
},
"group": {
"groupType": "projectContributor"
}
}
}
]
"#
$uri = "$orgURL/_apis/userentitlements/$userId`?api-version=5.1-preview.2"
Invoke-RestMethod -Uri $uri -ContentType "application/json-patch+json" -Body $b -Method PATCH -Headers #{ Authorization = ("Basic {0}" -f $base64AuthInfo)}
The error I am getting is this:
projectId","typeName":"System.ArgumentException, mscorlib","typeKey":"ArgumentException","errorCode":0,"eventId":0}
At line:20 char:1
+ Invoke-RestMethod -Uri $uri -ContentType "application/json-patch+json ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
Any help / examples are appreciated.
I have gone through all the API documentation for Azure DevOps API.
I got the same error using User Entitlement rest api.
It worked for me with Remove Member From Group rest api.
DELETE https://vsaex.dev.azure.com/{organization}/_apis/GroupEntitlements/{groupId}/members/{memberId}?api-version=5.1-preview.1
When a user is added to a project as Project Contributors. This user will be added to group [ProjectName]\\Contributors of this Project.
You can then use Group List rest api to get the group id of [ProjectName]\\Contributors. The {memberId} of above Remove Member From Group api is user's userId. Then you can just call above api to remove the user from the project contributors group.
Please try this:
$b= #"
[
{
"op": "remove",
"path": "/projectEntitlements/$projectID",
"value": {
"projectRef": {
"id": "$projectID"
},
"group": {
"groupType": "projectContributor"
}
}
}
]
"#
And since you are removing value under this path I'm not sure if you need value, so this should provide you the same:
$b= #"
[
{
"op": "remove",
"path": "/projectEntitlements/$projectID",
"value": ""
}
]
"#
I am trying to use the Invoke-Restmethod to call a set of API's, but it fails with the below error, i have also posted the same json format, can some let me know what could be wrong ?
### Ignore TLS/SSL errors
add-type #"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}}
"#
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
#Create URL string for Invoke-RestMethod
$urlsend = 'https://' + 'vrslcm-01a.corp.local/lcm/api/v1/' + '/login'
#Credential
$Username = "admin#localhost"
$password = "VMware1!"
$basicAuth = "Basic " + [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$($Username):$Password"))
$headers = #{
"description"= "Testing Authentication"
}
$body = #{
$raw= '{\n\t\"username\": \"admin#localhost\",\n\t\"password\": \"vmware\"\n}'
"mode"= $raw
}
Invoke-RestMethod -Method POST -uri $urlsend -Headers $headers -Body $body -ContentType 'application/json'
Here is the sample jSON which iam trying to invoke via powershell, it consists of the header and the body. I need to understand how we could call the same jSON POSTMAN example via the PowerShell Invoke-RestMethod
"item": [
{
"name": "authorization",
"description": "",
"item": [
{
"name": "Login",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"var response=JSON.parse(responseBody)",
"postman.setEnvironmentVariable(\"token\", response.token)"
]
}
}
],
"request": {
"url": "{{Server}}/lcm/api/v1/login",
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json",
"description": ""
}
],
"body": {
"mode": "raw",
"raw": "{\n\t\"username\": \"admin#localhost\",\n\t\"password\": \"vmware\"\n}"
},
"description": ""
},
"response": []
},
{
"name": "Logout",
"request": {
"url": "{{Server}}/lcm/api/v1/logout",
"method": "POST",
"header": [
{
"key": "x-xenon-auth-token",
"value": "{{token}}",
"description": ""
}
],
"body": {},
"description": ""
},
"response": []
}
]
},
make $raw to a hashtable like
$raw = #{
username=$Username
password=$Password
}
add this hashtable to the $body hashtable
$body = #{
mode= $raw
}
but now it still is a hashtable the api cannot use. thus convert it to json like
$jsonBody = $body | ConvertTo-Json
using $jsonBody should then work when used like
Invoke-RestMethod -Method POST -uri $urlsend -Headers $headers -Body $jsonBody -ContentType 'application/json'
Like the error states, the problem is your hash definition.
A null key is not allowed in a hash literal.
PowerShell tries to evaluate $raw as a hash table key. Since it hasn't been defined before it is null and fails because null is not allowed. Try it like this:
$raw= '{\n\t\"username\": \"admin#localhost\",\n\t\"password\": \"vmware\"\n}'
$body = #{
"mode"= $raw
}
I'm trying to make a request to the AccessPointsDetails endpoint of the Cisco Prime API and then loop through that to get all URL objects for the AccessPoints so I can get data on each of them.
I get the following output:
VERBOSE: Making request to: #{#type=AccessPointDetails; #url=https://cpist/webacs/api/v3/data/AccessPointDetails/3373245; $=3373245}
VERBOSE: Making request to: #{#type=AccessPointDetails; #url=https://cpist/webacs/api/v3/data/AccessPointDetails/3413720; $=3413720}
VERBOSE: Making request to: #{#type=AccessPointDetails; #url=https://cpist/webacs/api/v3/data/AccessPointDetails/3432295; $=3432295}
VERBOSE: Making request to: #{#type=AccessPointDetails; #url=https://cpist/webacs/api/v3/data/AccessPointDetails/3432310; $=3432310}
VERBOSE: Making request to: #{#type=AccessPointDetails; #url=https://cpist/webacs/api/v3/data/AccessPointDetails/3462672; $=3462672}
VERBOSE: Making request to: #{#type=AccessPointDetails; #url=https://cpist/webacs/api/v3/data/AccessPointDetails/3497980; $=3497980}
VERBOSE: Making request to: #{#type=AccessPointDetails; #url=https://cpist/webacs/api/v3/data/AccessPointDetails/3497993; $=3497993}
VERBOSE: Making request to: #{#type=AccessPointDetails; #url=https://cpist/webacs/api/v3/data/AccessPointDetails/3512621; $=3512621}
VERBOSE: Making request to: #{#type=AccessPointDetails; #url=https://cpist/webacs/api/v3/data/AccessPointDetails/3526872; $=3526872}
VERBOSE: Making request to: #{#type=AccessPointDetails; #url=https://cpist/webacs/api/v3/data/AccessPointDetails/16162527426; $=16162527426}
#type #url $
----- ---- -
AccessPointDetails https://cpist/webacs/api/v3/data/AccessPointDetails/3373245 3373245
AccessPointDetails https://cpist/webacs/api/v3/data/AccessPointDetails/3413720 3413720
AccessPointDetails https://cpist/webacs/api/v3/data/AccessPointDetails/3432295 3432295
AccessPointDetails https://cpist/webacs/api/v3/data/AccessPointDetails/3432310 3432310
AccessPointDetails https://cpist/webacs/api/v3/data/AccessPointDetails/3462672 3462672
AccessPointDetails https://cpist/webacs/api/v3/data/AccessPointDetails/3497980 3497980
AccessPointDetails https://cpist/webacs/api/v3/data/AccessPointDetails/3497993 3497993
AccessPointDetails https://cpist/webacs/api/v3/data/AccessPointDetails/3512621 3512621
AccessPointDetails https://cpist/webacs/api/v3/data/AccessPointDetails/3526872 3526872
AccessPointDetails https://cpist/webacs/api/v3/data/AccessPointDetails/16162527426 16162527426
Here is the response JSON for one store as well:
{
"queryResponse": {
"#last": 9,
"#first": 0,
"#count": 10,
"#type": "AccessPointDetails",
"#requestUrl": "https://cpist/webacs/api/v3/data/AccessPointDetails?.group=0026",
"#responseType": "listEntityIds",
"#rootUrl": "https://cpist/webacs/api/v3/data",
"entityId": [
{
"#type": "AccessPointDetails",
"#url": "https://cpist/webacs/api/v3/data/AccessPointDetails/3373245",
"$": "3373245"
},
{
"#type": "AccessPointDetails",
"#url": "https://cpist/webacs/api/v3/data/AccessPointDetails/3413720",
"$": "3413720"
},
{
"#type": "AccessPointDetails",
"#url": "https://cpist/webacs/api/v3/data/AccessPointDetails/3432295",
"$": "3432295"
},
{
"#type": "AccessPointDetails",
"#url": "https://cpist/webacs/api/v3/data/AccessPointDetails/3432310",
"$": "3432310"
},
{
"#type": "AccessPointDetails",
"#url": "https://cpist/webacs/api/v3/data/AccessPointDetails/3462672",
"$": "3462672"
},
{
"#type": "AccessPointDetails",
"#url": "https://cpist/webacs/api/v3/data/AccessPointDetails/3497980",
"$": "3497980"
},
{
"#type": "AccessPointDetails",
"#url": "https://cpist/webacs/api/v3/data/AccessPointDetails/3497993",
"$": "3497993"
},
{
"#type": "AccessPointDetails",
"#url": "https://cpist/webacs/api/v3/data/AccessPointDetails/3512621",
"$": "3512621"
},
{
"#type": "AccessPointDetails",
"#url": "https://cpist/webacs/api/v3/data/AccessPointDetails/3526872",
"$": "3526872"
},
{
"#type": "AccessPointDetails",
"#url": "https://cpist/webacs/api/v3/data/AccessPointDetails/16162527426",
"$": "16162527426"
}
]
}
}
I feel I may be a bit burnt and making a silly oversight?
Solution Code (See Accepted Answer):
Function allAP {
Write-Verbose "Getting all APs for Store $Store"
$storeApReq = "https://cpist/webacs/api/v3/data/AccessPointDetails.json?.group=$Store"
Write-Verbose "Making request to $storeApReq"
$Global:apIdListReq = Invoke-RestMethod -uri $storeApReq -method Get -ContentType 'application/json' -headers #{ Authorization = $auth }
$Global:apIdList = $apIdListReq.queryResponse.entityId
$Global:apIdCount = $apIdListReq.queryResponse."#count"
Write-Verbose "Found $siteAPCount APs in Sites Database. $apIdCount out of $siteAPCount APs found."
Write-Verbose "Response Received: $apIdList"
$Global:apIdURL = $apIdListReq.queryResponse.entityId
$Global:apURL = $apIdUrl.'#url'
Write-Verbose "Starting a loop."
ForEach($apIdURL in $apIdList) {
Invoke-RestMethod -uri $apURL -method Get -ContentType 'application/json' -headers #{ Authorization = $auth }
Write-Verbose "Making request to: $apURL"
$apURL
}
}
The biggest issue you're having is accessing the members of your returned object incorrectly. The Invoke-RestMethod is returning a pscustomobject representation of the JSON the application returns to you. Your example JSON looked like this:
{
"queryResponse": {
"#last": 9,
"#first": 0,
"#count": 10,
"#type": "AccessPointDetails",
"#requestUrl": "https://cpist/webacs/api/v3/data/AccessPointDetails?.group=0026",
"#responseType": "listEntityIds",
"#rootUrl": "https://cpist/webacs/api/v3/data",
"entityId": [
{
"#type": "AccessPointDetails",
"#url": "https://cpist/webacs/api/v3/data/AccessPointDetails/3373245",
"$": "3373245"
},
...
]
}
}
This gets transformed into pscustomobject:
[pscustomobject]#{
'queryResponse' = [pscustomobject]#{
'#last' = 9
'#first' = 0
'#count' = 10
'#type' = 'AccessPointDetails'
'#requestUrl' = 'https://cpist/webacs/api/v3/data/AccessPointDetails?.group=0026'
'#responseType' = 'listEntityIds'
'#rootUrl' = 'https://cpist/webacs/api/v3/data'
'entityId' = #(
[pscustomobject]#{
'#type' = 'AccessPointDetails'
'#url' = 'https://cpist/webacs/api/v3/data/AccessPointDetails/3373245'
'$' = '3373245'
}
...
)
}
}
I'm unsure why accessing .'#url' isn't working for you. Below is a working implementation of what you're trying to do.
function Get-AccessPoint
{
param
(
[Parameter(Position = 0, Mandatory)]
[ValidateNotNullOrEmpty()]
[string]
$Store
)
# function is accessing above-scope variables $auth and $siteAPCount
Write-Verbose "Retrieving APs for store $Store"
$uri = "https://cpist/webacs/api/v3/data/AccessPointDetails.json?.group=$Store"
Write-Verbose "Request: $uri"
$global:apIdListReq = Invoke-RestMethod -Uri $uri -ContentType application/json -Headers #{Authorization = $auth}
$global:apIdList = $apIdListReq.queryResponse.entityId
$global:apIdCount = $apIdListReq.'#count'
Write-Verbose "Found $siteAPCount APs in Sites Database. $apIdCount out of $siteAPCount APs found."
foreach ($entity in $apIdList)
{
Write-Verbose "Making request to $($entity.'#url')"
Invoke-RestMethod -Uri $entity.'#url' -ContentType application/json -Headers #{Authorization = $auth}
}
}
I am trying to create a bug in TFS using REST API in PowerShell with the code below, but I'm unable to figure out how to fill the $Bug variable with names of those param's and data.
Param(
[string]$vstsAccount = "MyAccountName",
[string]$projectName = "ProjectName",
[string]$keepForever = "true",
[string]$user = "",
[string]$token = "Mytoken"
)
# Base64-encodes the Personal Access Token (PAT) appropriately
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))
#$uri = "https://$($vstsAccount).visualstudio.com/$($projectName)/_apis/wit/workitems/$Bug?api-version=2.2"
$result = Invoke-RestMethod -Uri $uri -Method Get -ContentType "application/json" -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)}
I could find a sample for C# here, but not for PowerShell. Any help would be appreciated.
Cheers
You need to create a JSON body to use the REST API to create a work item in PowserShell, and the Content-Type should be application/json-patch+json, also use PATCH method. See Create a work item for details.
You can reference below sample PowerShell script to create a bug:
Param(
[string]$baseurl = "http://server:8080/tfs/DefaultCollection",
[string]$projectName = "ProjectName",
[string]$keepForever = "true",
[string]$user = "username",
[string]$token = "token"
)
# Base64-encodes the Personal Access Token (PAT) appropriately
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))
function CreateJsonBody
{
$value = #"
[
{
"op": "add",
"path": "/fields/System.Title",
"value": "0925Bug"
},
{
"op": "add",
"path": "/fields/System.AreaPath",
"value": "LCScrum"
},
{
"op": "add",
"path": "/fields/System.IterationPath",
"value": "LCScrum\\Sprint 1"
},
{
"op": "add",
"path": "/fields/System.Tags",
"value": "Tag0921;Tag0926;Tag0927;Tag0928"
},
{
"op": "add",
"path": "/fields/Microsoft.VSTS.Common.Activity",
"value": "Development"
},
{
"op": "add",
"path": "/fields/Microsoft.VSTS.Scheduling.Effort",
"value": "8"
},
{
"op": "add",
"path": "/fields/Microsoft.VSTS.Common.ValueArea",
"value": "Business"
},
{
"op": "add",
"path": "/fields/Microsoft.VSTS.Common.Severity",
"value": "3 - Medium"
},
{
"op": "add",
"path": "/relations/-",
"value":
{
"rel": "System.LinkTypes.Dependency-Forward",
"url": "http://server:8080/tfs/DefaultCollection/_apis/wit/workItems/324",
"attributes":
{
"usage": "workItemLink",
"editable": false,
"enabled": true,
"acyclic": true,
"directional": true,
"singleTarget": true,
"topology": "dependency"
}
}
},
{
"op": "add",
"path": "/relations/-",
"value":
{
"rel": "System.LinkTypes.Hierarchy-Reverse",
"url": "http://server:8080/tfs/DefaultCollection/_apis/wit/workItems/58",
"attributes":
{
"usage": "workItemLink",
"editable": false,
"enabled": true,
"acyclic": true,
"directional": true,
"singleTarget": false,
"topology": "tree"
}
}
}
]
"#
return $value
}
$json = CreateJsonBody
$uri = "$baseurl/$($projectName)/_apis/wit/workitems/"+"$"+"bug?api-version=2.2"
Write-Host $uri
$result = Invoke-RestMethod -Uri $uri -Method Patch -Body $json -ContentType "application/json-patch+json" -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)}