Skip to content

Instantly share code, notes, and snippets.

@rfennell
Created December 20, 2019 17:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rfennell/fcf23a63d19d76a71ead4ec58096d44f to your computer and use it in GitHub Desktop.
Save rfennell/fcf23a63d19d76a71ead4ec58096d44f to your computer and use it in GitHub Desktop.
Finds an Azure Build agent, takes it off line then removes it registration
param
(
[parameter(Mandatory = $true, HelpMessage = "Azure DevOps PAT token")]
$pat,
[parameter(Mandatory = $true, HelpMessage = "URL of Azure DevOps instance e.g. https://dev.aure.com/myinstance")]
$url,
[parameter(Mandatory = $true, HelpMessage = "Azure DevOps Agent Pool name")]
$pool ,
[parameter(Mandatory = $true, HelpMessage = "Based name for agent to search for e.g MyAgent as part of B1MyAgent-123")]
$agentBaseName ,
[parameter(Mandatory = $true, HelpMessage = "Prefix for agent number e.g B as part of B1MyAgent-123")]
$prefix,
[parameter(Mandatory = $true, HelpMessage = "Agent number e.g 1 as part of B1MyAgent-123")]
$index,
)
function Get-WebClient {
param
(
[string]$pat,
[string]$ContentType = "application/json"
)
$wc = New-Object System.Net.WebClient
$wc.Headers["Content-Type"] = $ContentType
$pair = ":${pat}"
$bytes = [System.Text.Encoding]::ASCII.GetBytes($pair)
$base64 = [System.Convert]::ToBase64String($bytes)
$wc.Headers.Add("Authorization", "Basic $base64");
$wc
}
function Get-AgentPool {
param
(
$pat,
$url ,
$pool
)
$wc = Get-WebClient($pat)
# get the pool ID from the name
$uri = "$url/_apis/distributedtask/pools?poolName=$pool&api-version=5.1"
$jsondata = $wc.DownloadString($uri) | ConvertFrom-Json
$jsondata.value
}
function Get-Agent {
param
(
$pat,
$url ,
$poolid,
$agentBaseName,
$prefix,
$index
)
$wc = Get-WebClient($pat)
# get the agent, we can't use the url filter as the name has a random number
$uri = "$url/_apis/distributedtask/pools/$poolid/agents?api-version=5.1"
$jsondata = $wc.DownloadString($uri) | ConvertFrom-Json
$jsondata.value | where { $_.name -like "$prefix$index$agentBaseName-*" }
}
function Update-Agent {
param
(
$pat,
$url ,
$poolid,
$agentid,
$status
)
$wc = Get-WebClient($pat)
$uri = "$url/_apis/distributedtask/pools/$poolid/agents/$($agentID)?api-version=5.1"
# have to pass the ID too else there is a 404 error
$data = @{enabled = $status ; id = $agentid} | ConvertTo-Json
$jsondata = $wc.UploadString($uri,"PATCH", $data) | ConvertFrom-Json
}
function Delete-Agent {
param
(
$pat,
$url ,
$poolid,
$agentid
)
$pair = ":${pat}"
$bytes = [System.Text.Encoding]::ASCII.GetBytes($pair)
$base64 = [System.Convert]::ToBase64String($bytes)
Invoke-WebRequest -Uri "$url/_apis/distributedtask/pools/$poolid/agents/$($agentID)?api-version=5.1" -Method Delete -Headers @{"Authorization" ="Basic $base64"} | Out-Null
}
function Wait-UntilBuildFinishes {
param
(
$pat,
$url ,
$poolid,
$agentid
)
$wc = Get-WebClient($pat)
$uri = "$url/_apis/distributedtask/pools/$poolid/jobrequests?api-version=5.1"
$jsondata = $wc.DownloadString($uri) | ConvertFrom-Json
write-host "Checking for running builds on agent"
$runningBuildUri = ""
foreach ($job in $jsondata.value) {
if ($job.reservedAgent.id -eq $agentid) {
if ($job.owner._links.self.href -notlike '*maintenancejobs*') {
$build = $wc.DownloadString($job.owner._links.self.href) | ConvertFrom-Json
if ($build.status -eq 'inProgress') {
"The build $($build.id) is $($build.status)"
$runningBuildUri = ($job.owner._links.self.href)
break;
}
}
}
}
if ($runningBuildUri -ne "") {
$exit = $false
while ($exit -ne $true) {
write-host 'Waiting for build to finish'
$build = $wc.DownloadString($runningBuildUri) | ConvertFrom-Json
$exit = $build.status -ne 'inProgress'
sleep -Seconds 15
}
}
}
write-host "Finding Agent Pool $pool"
$agentPool = Get-AgentPool -url $url -pat $pat -pool $pool
write-host "Finding Agent $prefix$index$agentbasename-XXX"
$agent = Get-Agent -url $url -pat $pat -poolid $agentPool.id -agentBaseName $agentBaseName -prefix $prefix -index $index
if ($agent -ne $null)
{
write-host "Check status of agent $($agent.name)"
if ($agent.enabled -eq $true)
{
write-host "Disabling the agent $($agent.name)"
Update-Agent -url $url -pat $pat -poolid $agentPool.id -agentid $agent.id -status $false
}
Wait-UntilBuildFinishes -url $url -pat $pat -poolid $agentPool.id -agentid $agent.id
write-host "Deleting the agent $($agent.name)"
Delete-Agent -url $url -pat $pat -poolid $agentPool.id -agentid $agent.id
} else {
write-host "No agent with a name in form $prefix$index$agentbasename-XXX is registered, so skipping"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment