TFS 2015 API remove agent from pool with PowerShell

2.6k views Asked by At

I'm working on removing an agent from a pool temporarily, install new software on the buildserver the agent is on, test that it works, and then add the agent to the pool again.

I would like to do that programmatically, either with PowerShell or if that isn't a possibility, then do it with C#.

The problem is that I can't find any documentation that can assist me on doing this, either through the TFS REST API or through the tools that come with Visual Studio.

So I'm specifically asking:

How do I remove a named agent from a build pool and how do I add a named agent back into the build pool?

I basically want the same functionality of going onto the web administration of TFS and unchecking/checking an agent in the pool.

When I try to enable/disable an agent with the information provided by starain-msft, I get the following error:

Invoke-RestMethod :
404 - File or directory not found.
Server Error

Later I removed much of the error, as I found out that issue lay in my company's proxy. Read here: Azure DevOps Services REST API Reference

But I got it to work with the help of starain-msft.

The final solution looks like this:

Function TFSwebRequest {
    param
    (
        [ValidateNotNullOrEmpty()]
        [Parameter(Mandatory = $true)]
        [string] $Uri,

        [ValidateNotNullOrEmpty()]
        [Parameter(Mandatory = $true)]
        [string] $Method,

        [ValidateNotNullOrEmpty()]
        [string] $ContentType,

        [ValidateNotNullOrEmpty()]
        [string] $ContentBody,

        [ValidateNotNullOrEmpty()]
        [System.Net.WebHeaderCollection] $Headers
    )

    # Creating Webrequest from 'Uri'
    $webRequest = [System.Net.HttpWebRequest]::CreateHttp($Uri)

    $webRequest.UseDefaultCredentials = $true
    $webRequest.Method = $Method
    if ($Headers.Count -ne 0) {
        $webRequest.Headers = $Headers
    }
    if (![string]::IsNullOrEmpty($ContentType)) {
        $webRequest.ContentType = $ContentType
    }
    if (![string]::IsNullOrEmpty($ContentBody)) {
        $Body = [byte[]][char[]]$ContentBody
        $Stream = $webRequest.GetRequestStream();
        $Stream.Write($Body, 0, $Body.Length);
    }

    # Get webresponse to a variable
    try {
        [System.Net.WebResponse]$webResponse = $webRequest.GetResponse()
    }
    catch {
        $ErrorMessage = $_.Exception.Message
        Write-Host "TFSwebRequest Failed = " $ErrorMessage -ForegroundColor Red
    }

    # Stream webresponse to a string
    $webResponseStream = $webResponse.GetResponseStream()
    $streamReader = New-Object System.IO.StreamReader $webResponseStream
    $result = $streamReader.ReadToEnd() | ConvertFrom-Json

    return ,$result
}

$agentUri = "http://teamfoundation:8080/tfs/Main/_apis/distributedtask/pools/$($poolID)/agents/$($agentID)?api-version=2.3-preview.1"
$contentBody = @"
{
    "maxParallelism": 1,
    "id": INSERTID,
    "enabled": true #Or false
}
"@

$headers = New-Object System.Net.WebHeaderCollection
$headers.Add("X-HTTP-Method-Override", "PATCH")

TFSwebRequest -Uri $agentUri -Method "POST" -Headers $headers -ContentType "application/json" -ContentBody $contentBody
2

There are 2 answers

4
starian chen-MSFT On BEST ANSWER

REST API of the agent pool and agent:

Get agent pools (request method: GET):

http://[TFS URL]/_apis/distributedtask/pools?api-version=2.3-preview.1

Get agents of an agent pool (Request method: GET):

http://[TFS URL]/_apis/distributedtask/pools/[pool id]/agents?api-version=2.3-preview.1

Disable/enable build agent (Request method: PATCH)

http://[TFS URL]/_apis/distributedtask/pools/[pool id]/agents/[agent id]?api-version=2.3-preview.1

Body (Content-Type: application/json)

{
    "enabled": false,
    "id": [agent id],
    "maxParallelism": 1
}

Delete an agent from an agent pool (request method: DELETE):

http://[Tfs URL]/_apis/distributedtask/pools/[pool id]/agents/[agent id]?api-version=2.3-preview.1

Simple sample to call REST API (PowerShell):

Param(
   [string]$vstsAccount = "<VSTS-ACCOUNT-NAME>",
   [string]$projectName = "<PROJECT-NAME>",
   [string]$buildNumber = "<BUILD-NUMBER>",
   [string]$keepForever = "true",
   [string]$user = "",
   [string]$token = "<PERSONAL-ACCESS-TOKEN>"
)

# 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/DefaultCollection/$($projectName)/_apis/build/builds?api-version=2.0&buildNumber=$($buildNumber)"
$result = Invoke-RestMethod -Uri $uri -Method Get -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}

For details: Calling VSTS APIs with PowerShell

C# code to call REST API:

String MyURI = "REST API URL";
WebRequest WReq = WebRequest.Create(MyURI);
WReq.Credentials =
    new NetworkCredential("[user name]", "[password]", "[domain]");

WebResponse response = WReq.GetResponse();
Console.WriteLine(((HttpWebResponse)response).StatusDescription);
Stream dataStream = response.GetResponseStream();

StreamReader reader = new StreamReader(dataStream);

string responseFromServer = reader.ReadToEnd();

Console.WriteLine(responseFromServer);

On the other hand, you need to restart the build agent after you install new software to the agent machine in order to recognize them.

0
Cece Dong - MSFT On

There is no such API to create or remove an agent from the agent pool. And it's not needed to write your own script. When you download the agent, you just need to run a command prompt as Administrator, and then run ConfigureAgent.cmd on your build agent machine:

C:\Agent\ConfigureAgent.cmd

Then respond to the prompts. Check Deploy an agent on Windows for TFS 2015