Error managing taskgroups using the TFS api and builtin OAuth System.Accesstoken - powershell

I've created a powershell script that does some updating of taskgroups that we need in our company. I do this by calling the route "/_apis/distributedtask/taskgroups".
This script works well when I use a personal access token from myself. However, I need it to be run by a build agent as part of a release process.
To manage this I have enabled "Allow scripts to access OAuth token" as outlined in
VSTS - allow Scripts to Access OAuth Token in Release Managment
I have then in my powershell script used the logic outlined here
https://learn.microsoft.com/sv-se/vsts/build-release/actions/scripts/powershell#oauth
to gain access to the token and include it in my api calls to the TFS api. I am successfull in retrieving the taskgroups this way, but when I try to update one I get
[error]Invoke-RestMethod : TF400813: Resource not available for
anonymous access. Client authentication required.
To exclude permisson problems I have given the build agent account "Project administrator" persmissions as well as "Build administrator" and "Release administrator". Any suggestions?

It appears that OAuth token is not registered for the server.
Please refer to slautebach's solution in this thread for troubleshooting:
It appears that during our upgrade TFS did not register a OAuth token
for the server.
The SQL recommend to execute was: using the FQDN (ie
tfs-server.doman.com)
EXEC prc_SetRegistryValue 1,'#\Configuration\OAuth\TrustedIssuers\tfs-sever.domain.com\','Microsoft.TeamFoundation.Framework.Server.OAuth.ClientAuthTokenValidator'
This prevented all users from logging in after a TFS server reboot. We
then tried with just the server name (ie tfs-server)
EXEC prc_SetRegistryValue 1,'#\Configuration\OAuth\TrustedIssuers\tfs-server\','Microsoft.TeamFoundation.Framework.Server.OAuth.ClientAuthTokenValidator'
This than allowed normal user login and the builds to finally work
after a server reboot and re-registering all the build agent.
If that still not work, as a workaround you can use basic authorization to do that:
Below PowerShell script works for me:
Param(
[string]$baseurl = "http://server:8080/tfs/DefaultCollection",
[string]$projectName = "ProjectName",
[string]$keepForever = "true",
[string]$user = "username",
[string]$token = "password"
)
# Base64-encodes the Personal Access Token (PAT) appropriately
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))
#Need to change revision every time
function CreateJsonBody
{
$value = #"
{
"tasks": [
{
"displayName": "PowerShell Script",
"alwaysRun": false,
"continueOnError": false,
"condition": "succeeded()",
"enabled": true,
"timeoutInMinutes": 0,
"inputs": {
"scriptType": "filePath",
"scriptName": "$/TFVC-Scrum2018/ConsoleApp1/PS/0129-GetIISsites.ps1",
"arguments": "",
"workingFolder": "",
"inlineScript": "# You can write your powershell scripts inline here. \n# You can also pass predefined and custom variables to this scripts using arguments\n\n Write-Host \"Hello World\"",
"failOnStandardError": "true"
},
"task": {
"id": "e213ff0f-5d5c-4791-802d-52ea3e7be1f1",
"versionSpec": "1.*",
"definitionType": "task"
}
},
{
"displayName": "PowerShell Script",
"alwaysRun": false,
"continueOnError": false,
"condition": "succeeded()",
"enabled": true,
"timeoutInMinutes": 0,
"inputs": {
"scriptType": "filePath",
"scriptName": "$/TFVC-Scrum2018/ConsoleApp1/PS/0129.ps1",
"arguments": "",
"workingFolder": "",
"inlineScript": "# You can write your powershell scripts inline here. \n# You can also pass predefined and custom variables to this scripts using arguments\n\n Write-Host \"Hello World\"",
"failOnStandardError": "true"
},
"task": {
"id": "e213ff0f-5d5c-4791-802d-52ea3e7be1f1",
"versionSpec": "1.*",
"definitionType": "task"
}
}
],
"visibility": [
"Build",
"Release"
],
"runsOn": [
"Agent",
"DeploymentGroup"
],
"owner": "d122de31-36a7-415c-aa42-b6d09295d5a0",
"revision": 2,
"createdBy": {
"id": "d122de31-36a7-415c-aa42-b6d09295d5a0",
"displayName": "xxx",
"uniqueName": "xxx"
},
"createdOn": "2018-02-02T07:17:45.25Z",
"modifiedBy": {
"id": "d122de31-36a7-415c-aa42-b6d09295d5a0",
"displayName": "xxx",
"uniqueName": "xxx"
},
"modifiedOn": "2018-02-02T07:17:45.25Z",
"id": "4c8c1d32-52bc-492e-ba4d-c9b1b363bcdf",
"name": "0203",
"version": {
"major": 1,
"minor": 0,
"patch": 0,
"isTest": false
},
"serverOwned": false,
"contentsUploaded": true,
"iconUrl": "/tfs/_static/tfs/Dev16.M122.5/_content/icon-meta-task.png",
"hostType": null,
"packageType": "",
"packageLocation": "",
"sourceLocation": "",
"minimumAgentVersion": "*",
"friendlyName": "0203",
"description": "test0203",
"category": "Build",
"helpMarkDown": "",
"definitionType": "metaTask",
"author": "xxx",
"demands": [],
"groups": [
{
"name": "PowerShell Script",
"displayName": "PowerShell Script",
"isExpanded": true,
"visibleRule": ""
},
{
"name": "PowerShell Script",
"displayName": "PowerShell Script",
"isExpanded": true,
"visibleRule": ""
}
],
"inputs": [],
"satisfies": [],
"sourceDefinitions": [],
"dataSourceBindings": [],
"instanceNameFormat": "Task group: 0203 ",
"execution": {}
}
"#
return $value
}
$json = CreateJsonBody
$uri = "$baseurl/$($projectName)/_apis/distributedtask/taskgroups?api-version=4.0-preview.1"
Write-Host $uri
$result = Invoke-RestMethod -Uri $uri -Method Put -Body $json -ContentType "application/json" -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)}

It was actually a permission issue. I was assuming that the OAuth token being used would be from the user that the build agent was running as, but this was not the case.
I resolved this by giving 'Project Collection Build Service' user "Edit task group" permissions on each collections task groups.

Related

Error while trying to create a release definition using Azure DevOps Rest API

I am using below script to create a release definition in Azure DveOps with a PowerShell script, but its failing with error message as below. Not sure where am giving incorrect details.
Invoke-RestMethod :
{"$id":"1","innerException":null,"message":"VS402903: The specified
value is not convertible to type ReleaseDefinition. Make sure it is
convertible to type ReleaseDefinition and try again."
Code snippet is:
Param(
[string]$organisation = "ORGNAME",
[string]$project = "PROJECTNAME",
[string]$keepForever = "true",
[string]$user = "userid",
[string]$token = "tokenID" )
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))
Write-host $base64AuthInfo
$postresults = "https://vsrm.dev.azure.com/$organisation/$project/_apis/release/definitions?api-version=6.0"
Write-host $postresults
$body =
#"
{ "name": "New release pipeline ",
"comment": "test",
"definitionId": 860,
"description": "Create Release from PowerShell",
"artifacts": [],
"isDraft": false,
"reason": "Demo purpose",
"manualEnvironments": null,
"environmentsMetadata": null,
"properties": null,
"variables": null
"environments": [
{
"name": "PROD",
"preDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": false,
"isNotificationOn": false,
"approver": {
"displayName": null,
"id": ""
},
"id": 0
}
]
},
"postDeployApprovals": {
"approvals": [
{
"rank": 1,
"isAutomated": true,
"isNotificationOn": false,
"id": 0
}
]
},
"deployPhases": [
{
"deploymentInput": {
"parallelExecution": {
"parallelExecutionType": "none"
},
"skipArtifactsDownload": false,
"artifactsDownloadInput": {},
"queueId": 391,
"demands": [],
"enableAccessToken": false,
"timeoutInMinutes": 0,
"jobCancelTimeoutInMinutes": 1,
"condition": "succeeded()",
"overrideInputs": {}
},
"rank": 1,
"phaseType": "agentBasedDeployment",
"name": "Run on agent",
"workflowTasks": []
}
],
"retentionPolicy": {
"daysToKeep": 30,
"releasesToKeep": 3,
"retainBuild": true
}
}
],
"path": "\\",
"releaseNameFormat": "Release",
"description": ""
}
"# | ConvertTo-Json -Depth 100
$result = Invoke-RestMethod -Uri $postresults -Method Post -Body $body -ContentType "application/json" -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)}
if ($result.count -eq 0)
{
throw "Unable to locate Release Definition Id $($definitionId)"
}
else
{
Write-host "Success!!!"
}
You have few issues in the json body:
The description exist twice.
You have missing , near the "variables": null.
You need to specify a valid id in the preDeployApprovals:
"approver": {
"displayName": null,
"id": "PUT-HERE-ID"
},
Add the above section also to the
You don't need to convert it again to json, remove the | ConvertTo-Json -Depth 100 from the code.

Deploying an Azure VM and Users with an ARM template and DSC

I am taking my first look at creating a DSC (Desired State Configuration) to go with an ARM (Azure Resource Manager) template to deploy a Windows Server 2016 and additional local user accounts. So far the ARM template works fine and for the DSC file I am using simple example to test functionality. The deployment works fine until I try to pass a username/password so I can create a local Windows user account. I can't seem to make this function work at all (see the error message below).
My question is, how do I use the ARM template to pass the credentials (password) to the DSC (mof) file so that the user can be created without having to explicitly allow plain text passwords (which is not a good practice)?
This is what I have tried:
DSC file
Configuration xUser_CreateUserConfig {
[CmdletBinding()]
Param (
[Parameter(Mandatory = $true)]
[string]
$nodeName,
[Parameter(Mandatory = $true)]
[System.Management.Automation.PSCredential]
[System.Management.Automation.Credential()]
$Credential
)
Import-DscResource -ModuleName xPSDesiredStateConfiguration
Node $nodeName {
xUser 'CreateUserAccount' {
Ensure = 'Present'
UserName = Split-Path -Path $Credential.UserName -Leaf
Password = $Credential
}
}
}
Azure ARM Template Snippet 1st Method
"resources": [
{
"apiVersion": "2016-03-30",
"type": "extensions",
"name": "Microsoft.Powershell.DSC",
"location": "[parameters('location')]",
"tags": {
"DisplayName": "DSC",
"Dept": "[resourceGroup().tags['Dept']]",
"Created By": "[parameters('createdBy')]"
},
"dependsOn": [
"[resourceId('Microsoft.Compute/virtualMachines', concat(variables('vmNamePrefix'), copyIndex(1)))]"
],
"properties": {
"publisher": "Microsoft.Powershell",
"type": "DSC",
"typeHandlerVersion": "2.19",
"autoUpgradeMinorVersion": true,
"settings": {
"wmfVersion": "latest",
"modulesUrl": "[concat(variables('_artifactslocation'), '/', variables('dscArchiveFolder'), '/', variables('dscArchiveFileName'))]",
"configurationFunction": "xCreateUserDsc.ps1\\xUser_CreateUserConfig",
"properties": {
"nodeName": "[concat(variables('vmNamePrefix'), copyIndex(1))]",
"Credential": {
"UserName": "[parameters('noneAdminUsername')]",
"Password": "PrivateSettingsRef:UserPassword"
}
}
},
"protectedSettings": {
"Items": {
"UserPassword": "[parameters('noneAdminUserPassword')]"
}
}
}
}
]
Error message
The resource operation completed with terminal provisioning state 'Failed'. VM has reported a failure when processing extension 'Microsoft.Powershell.DSC'. Error message: \\"The DSC Extension received an incorrect input: Compilation errors occurred while processing configuration 'xUser_CreateUserConfig'. Please review the errors reported in error stream and modify your configuration code appropriately. System.InvalidOperationException error processing property 'Password' OF TYPE 'xUser': Converting and storing encrypted passwords as plain text is not recommended. For more information on securing credentials in MOF file, please refer to MSDN blog: http://go.microsoft.com/fwlink/?LinkId=393729
This error message does not help
Azure ARM Template snippet 2nd Method
"resources": [
{
"apiVersion": "2018-10-01",
"type": "extensions",
"name": "Microsoft.Powershell.DSC",
"location": "[parameters('location')]",
"tags": {
"DisplayName": "DSC",
"Dept": "[resourceGroup().tags['Dept']]",
"Created By": "[parameters('createdBy')]"
},
"dependsOn": [
"[resourceId('Microsoft.Compute/virtualMachines', concat(variables('vmNamePrefix'), copyIndex(1)))]"
],
"properties": {
"publisher": "Microsoft.Powershell",
"type": "DSC",
"typeHandlerVersion": "2.9",
"autoUpgradeMinorVersion": true,
"settings": {
"wmfVersion": "latest",
"configuration": {
"url": "[concat(variables('_artifactslocation'), '/', variables('dscArchiveFolder'), '/', variables('dscArchiveFileName'))]",
"script": "xCreateUserDsc.ps1",
"function": "xUser_CreateUserConfig"
},
"configurationArguments": {
"nodeName": "[concat(variables('vmNamePrefix'), copyIndex(1))]"
},
"privacy": {
"dataCollection": "Disable"
}
},
"protectedSettings": {
"configurationArguments": {
"Credential": {
"UserName": "[parameters('noneAdminUsername')]",
"Password": "[parameters('noneAdminUserPassword')]"
}
}
}
}
}
]
Error Message
VM has reported a failure when processing extension 'Microsoft.Powershell.DSC'. Error message: "The DSC Extension received an incorrect input: A parameter cannot be found that matches parameter name '$credential.Password'. Another common error is to specify parameters of type PSCredential without an explicit type. Please be sure to use a typed parameter in DSC Configuration, for example: configuration Example param([PSCredential] $UserAccount). Please correct the input and retry executing the extension. More information on troubleshooting is available at https://aka.ms/VMExtensionDSCWindowsTroubleshoot
This does not help!
I have been trying to solve this error for a couple of days. I have Googled for other example but can only find example of people deploying Web Server and Microsoft's documentation is no help because it tells you to use both of the above methods. When method 1 is the old way (according to Microsoft). So, any help will be much appreciated.
this is how I was setting up parameter in the configuration:
# Credentials
[Parameter(Mandatory)]
[System.Management.Automation.PSCredential]$Admincreds,
and then in the template:
"properties": {
"publisher": "Microsoft.Powershell",
"type": "DSC",
"typeHandlerVersion": "2.19",
"autoUpgradeMinorVersion": true,
"settings": {
"configuration": xxx // doesn't matter for this question
"configurationArguments": yyy // doesn't matter for this question
},
"protectedSettings": {
"configurationArguments": {
"adminCreds": {
"userName": "someValue",
"password": "someOtherValue"
}
}
}
}
Links to working stuff:
https://github.com/Cloudneeti/PCI_Reference_Architecture/blob/master/templates/resources/AD/azuredeploy.json#L261
https://github.com/Cloudneeti/PCI_Reference_Architecture/blob/master/artifacts/configurationscripts/ad-domain.ps1#L11
ps. you might also need to do this. Honestly, I dont remember ;)

Azure ARM Template for runbook with Powershell file from Azure Git Repo

We are trying to deploy a runbook with Powershell that queries Log Analytics periodically. We have it working on the portal and now we are trying tobuild a ARM Template for doing future deployments to other environments. We have our ARM (json) template and the PS1 file in the same Azure Devops Git repo and we even tried hard coding the path of PS1 file in the template but it doesnt work. Can someone please help us here on what we are doing wrong. Following is the ARM Template:-
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"automationAccountName": {
"type": "string",
"defaultValue": "Automation-XXX-INFRA-MONITORING",
"metadata": {
"description": "Automation Account"
}
},
"automationRegion": {
"defaultValue": "eastus2",
"type": "string",
"allowedValues": [
"westeurope",
"southeastasia",
"eastus2",
"southcentralus",
"japaneast",
"northeurope",
"canadacentral",
"australiasoutheast",
"centralindia",
"westcentralus"
],
"metadata": {
"description": "Specify the region for your automation account"
}
},
"_artifactsLocation": {
"type": "string",
"defaultValue": "https://ABCD.visualstudio.com/3Pager/_git/Infrastructure?path=%2FAzure.Infra%2FAppInsights%2FMonthOverMonthTrendAnalysisReport.ps1&version=GBmaster",
"metadata": {
"description": "URI to artifacts location"
}
},
"_artifactsLocation1": {
"type": "string",
"defaultValue": "https://ABCD.visualstudio.com/3Pager/_git/Infrastructure?path=%2FAzure.Infra%2FAppInsights%2FMonthOverMonthTrendAnalysisReport.ps1&version=GBmaster",
"metadata": {
"description": "URI to artifacts location"
}
}
},
"variables": {
"asrScripts": {
"runbooks": [
{
"name": "Test_Runbook",
"url": "[parameters('_artifactsLocation')]",
"version": "1.0.0.0",
"type": "PowerShell",
"description": "Runbook for month over month trend analysis report"
}
]
}
},
"resources": [
{
"apiVersion": "2015-10-31",
"type": "Microsoft.Automation/automationAccounts/runbooks",
"name": "[concat(parameters('automationAccountName'), '/', variables('asrScripts').runbooks[copyIndex()].Name)]",
"location": "[parameters('automationRegion')]",
"copy": {
"name": "runbooksLoop",
"count": "[length(variables('asrScripts').runbooks)]"
},
"properties": {
"description": "[variables('asrScripts').runbooks[copyIndex()].description]",
"runbookType": "[variables('asrScripts').runbooks[copyIndex()].type]",
"logProgress": false,
"logVerbose": true,
"publishContentLink": {
"uri":"[parameters('_artifactsLocation1')]",
"version": "[variables('asrScripts').runbooks[copyIndex()].version]" }
}
}
],
"outputs": {}
}
You are sending a URI to ARM telling it where to find the runbooks. When the AutomationAccount/runbooks resource type is created it will make a GET call to the publishContentLink.url in order to get the content from the URI. If Azure can't access that URI (presumably your visualstudio.com URI is not publicly accessible) then it won't be able to access the runbook content and the deployment will fail.
The solution is to make sure the publishContentLink URI is something accessible to the Azure Automation service. You can do this a couple ways:
Put the content in a publicly accessible URI such as Github or a public Blob Storage container.
Create a SAS token to the content. https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-manager-tutorial-secure-artifacts shows an example of how to do this with Azure Storage, or https://xebia.com/blog/setting-up-vsts-with-arm-templates/ for doing it with VSTS.
Leaving it here in case someone has similar issue. For a private Azure DevOps Repo it can be solved by Azure Function with HTTP trigger and following PowerShell script:
using namespace System.Net
# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)
# Interact with query parameters or the body of the request.
$adouri = $Request.Query.adouri
$pat = $Request.Query.pat
if (!$adouri){
$response = "Please pass uri"
Write-Warning "URI not passed" -Warning
} elseif (!$pat){
$response = "Please pass pat"
Write-Warning "PAT not passed" -Warning
} else {
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "", $pat)))
$headers = #{
"Authorization" = ("Basic {0}" -f $base64AuthInfo)
}
$response = Invoke-RestMethod -Uri $adouri -Method Get -ContentType "application/text" -Headers $headers
}
# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]#{
StatusCode = [HttpStatusCode]::OK
Body = $response
})
Once the function is ready, it can be called then directly from ARM template, e.g.:
"variables": {
"runbookUri": "https://[function name].azurewebsites.net/api/[trigger name]?adouri=https://dev.azure.com/[ADO Organization]/[ADO project]/_apis/git/repositories/[Repo]/items?path=%2F[folder]%2F[subfolder]%2Fscript.ps1&pat=[token]"
},
"resources": [
{
"type": "Microsoft.Automation/automationAccounts/runbooks",
"apiVersion": "2018-06-30",
"name": "[name]",
"location": "[location]"
"properties": {
"runbookType": "PowerShell",
"logVerbose": false,
"logProgress": false,
"logActivityTrace": 0,
"publishContentLink": {
"uri": "[variables('runbookUri')]"
}
}
}]
Token is just the Personal Access Token from Azure DevOps. To keep it secured it can be passed to the ARM template from a secret ADO variable or Azure KeyVault.
I overcame this limitation by using Terraform templates. They offer the possibility to publish custom content into a runbook by using local paths. So you can do this either directly from the Git repository file system (your pc), or by linking an Azure Pipeline to your repository and using the file as an artifact.
If interested, check https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/automation_runbook in the "Example Usage - custom content".

Powershell script for building CI/CD for Azure Data factory

I'm planning to build Continous integration and Deployment for Azure Data factory using PowerShell. So all the build and release process which can be done using VSTS has to be done using Powershell. If anyone can share any links or powershell scripts it would be helpful. Thanks
If you mean create build/release definition through PowerShell, you can do it through VSTS REST with PowerShell, simple code:
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "","{personal access token}")))
$body='{
"variables": {
"system.debug": {
"value": "false",
"allowOverride": true
}
},
"retentionRules": [
{
"branches": [
"+refs/heads/*"
],
"artifacts": [],
"artifactTypesToDelete": [
"FilePath",
"SymbolStore"
],
"daysToKeep": 10,
"minimumToKeep": 1,
"deleteBuildRecord": true,
"deleteTestResults": true
}
],
"properties": {},
"tags": [],
"jobAuthorizationScope": "projectCollection",
"jobTimeoutInMinutes": 60,
"jobCancelTimeoutInMinutes": 5,
"process": {
"phases": [
{
"steps": [
{
"environment": {},
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "Azure PowerShell script: FilePath",
"timeoutInMinutes": 0,
"condition": "succeeded()",
"task": {
"id": "72a1931b-effb-4d2e-8fd8-f8472a07cb62",
"versionSpec": "2.*",
"definitionType": "task"
},
"inputs": {
"ConnectedServiceNameSelector": "ConnectedServiceNameARM",
"ConnectedServiceName": "",
"ConnectedServiceNameARM": "aad18bbf-0333-41bf-99ea-674181d17ada",
"ScriptType": "FilePath",
"ScriptPath": "$/Scrum2015/ClassLibraryA/dbtest.ps1",
"Inline": "# You can write your azure powershell scripts inline here. \n# You can also pass predefined and custom variables to this script using arguments",
"ScriptArguments": "",
"TargetAzurePs": "LatestVersion",
"CustomTargetAzurePs": ""
}
}
],
"name": "Phase 1",
"refName": "Phase_1",
"condition": "succeeded()",
"target": {
"executionOptions": {
"type": 0
},
"allowScriptsAuthAccessOption": false,
"type": 1
},
"jobAuthorizationScope": "projectCollection",
"jobCancelTimeoutInMinutes": 1
}
],
"type": 1
},
"repository": {
"properties": {
"cleanOptions": "0",
"tfvcMapping": "{\"mappings\":[{\"serverPath\":\"$/Scrum2015/ClassLibraryA\",\"mappingType\":\"map\",\"localPath\":\"\\\\\"},{\"serverPath\":\"$/Scrum2015/ClassLibraryA/VS2010UltimTrial.iso\",\"mappingType\":\"cloak\",\"localPath\":\"\"},{\"serverPath\":\"$/Scrum2015/ClassLibraryA/tools\",\"mappingType\":\"cloak\",\"localPath\":\"\"}]}",
"labelSources": "0",
"labelSourcesFormat": "$(build.buildNumber)"
},
"id": "$/",
"type": "TfsVersionControl",
"name": "Scrum2015",
"defaultBranch": "$/Scrum2015/ClassLibraryA",
"rootFolder": "$/Scrum2015",
"clean": "false",
"checkoutSubmodules": false
},
"processParameters": {},
"quality": "definition",
"drafts": [],
"queue": {
"id": 179
},
"name": "PowerShellRest2VNext",
"path": "\\",
"type": "build",
"queueStatus": "enabled"
}'
$result = Invoke-RestMethod -Uri $uri -Method Post -ContentType "application/json" -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)} -Body $body
Note, you can create a sample build/release definition, then get it through VSTS REST API to get JSON content.
A blog that can help you: VSTS/TFS REST API: The basics and working with builds and releases
If you mean custom build/release task, you can refer to Add a build or release task, for powershell, change execution like this:
"execution": {
"PowerShell3": {
"target": "Hello.ps1",
"argumentFormat": ""
}
}
Regarding deploy azure data factory, you can refer to: How to deploy Azure Data Factory pipeline and its dependencies programatically using PowerShell (Do not need to call Login-AzureRMAccount and Select-AzureRMSubscrition, just add Azure PowerShell task to build/release definition).
A 3rd extension: Azure Data Factory

TFS 2015 Rest API - Create Build Definition

I'm trying to create a build definition in TFS using his api rest for it.
This is the microsoft docs for TFS Api Rest
I get status code 200 but...
This is what i get when I look into Tfs build definition
Anyone knows why this is happening?
Your second link provided a screenshot that a build definition with no tasks. It seems you had created a build definition successfully, but you didn't add tasks in the build definition.
Check your rest api to see whether you have "build": [] parameter with "task" in it as the following example shows:
"build": [
{
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "Build solution **\\*.sln",
"task": {
"id": "71a9a2d3-a98a-4caa-96ab-affca411ecda",
"versionSpec": "*"
},
"inputs": {
"solution": "**\\*.sln",
"msbuildArgs": "",
"platform": "$(platform)",
"configuration": "$(config)",
"clean": "false",
"restoreNugetPackages": "true",
"vsLocationMethod": "version",
"vsVersion": "latest",
"vsLocation": "",
"msbuildLocationMethod": "version",
"msbuildVersion": "latest",
"msbuildArchitecture": "x86",
"msbuildLocation": "",
"logProjectEvents": "true"
}
},
{
"enabled": true,
"continueOnError": false,
"alwaysRun": false,
"displayName": "Test Assemblies **\\*test*.dll;-:**\\obj\\**",
"task": {
"id": "ef087383-ee5e-42c7-9a53-ab56c98420f9",
"versionSpec": "*"
},
"inputs": {
"testAssembly": "**\\*test*.dll;-:**\\obj\\**",
"testFiltercriteria": "",
"runSettingsFile": "",
"codeCoverageEnabled": "true",
"otherConsoleOptions": "",
"vsTestVersion": "14.0",
"pathtoCustomTestAdapters": ""
}
}
],