本地 Azure DevOps Server 中给定池的 REST Api return AGENT.BUILDDIRECTORY 值是多少?
What REST Api return AGENT.BUILDDIRECTORY value for the given pool in Azure DevOps Server on-prem?
所以我获取了构建定义:
$bd = ...
它有池 ID:
C:\> $bd.queue.pool.id
90
C:\>
现在我可以使用 Url https://myserver.com/tfs/DefaultCollection/_apis/distributedtask/pools/90/agents?includeCapabilities=true
的功能获取池数据
我确实得到了很多信息,但是 Agent.BuildDirectory 没有:
C:\> $x = Invoke-RestMethod $Url -UseDefaultCredentials
C:\> $x.value.systemCapabilities[0].PSObject.Properties.Name |? { $_ -match '^Agent' }
Agent.Name
Agent.Version
Agent.ComputerName
Agent.HomeDirectory
Agent.OS
Agent.OSArchitecture
Agent.OSVersion
C:\>
给定一个有效的构建定义,我如何使用其余 API 为与其关联的每个本地代理获取 Agent.BuildDirectory?
如果您从 UI 访问代理的功能,您会发现没有 Agent.BuildDirectory
功能,因此您无法从 REST API 获取它。此外,Agent.BuildDirectory
是代理上的本地路径,其中创建了给定构建管道的所有文件夹,格式类似于 c:\agent_work\_work
,因此构建管道之间是不同的。
您可以从构建管道中获取此变量,或检查构建日志以获取路径。
我最终得到了以下函数:
function Invoke-ForEachBuildAgent(
[Parameter(Mandatory)]$BuildDefinition,
[Parameter(Mandatory)][scriptblock]$Action,
[pscredential]$Credential
)
{
function MapShare($AgentComputerName, $RemoteDirectory, $PSDrive, [pscredential]$Credential)
{
if ($Credential)
{
$Share = "\$AgentComputerName$($RemoteDirectory[0])`$"
$Mapped = $null
try
{
$Mapped = Test-Path $Share
}
catch
{
}
if (!$Mapped)
{
New-PSDrive $PSDrive FileSystem $Share -Credential $Credential > $null
}
}
}
$RelSourceFolderPath = "SourceRootMappinga33a8ed-f8fd-4c08-9f44-440ea9f20315$($BuildDefinition.Id)\SourceFolder.json"
$PSDrive = [guid]::NewGuid().ToString('N')
if (!$Credential -and ($env:USERNAME -ne INSERT_THE_DEFAULT_USER_NAME_HERE))
{
$Credential = Get-Credential -UserName INSERT_THE_DEFAULT_USER_NAME_WITH_DOMAIN_HERE -Message "Login to access the agents"
}
$Url = "$TfsInstanceUrl/_apis/distributedtask/pools/$($BuildDefinition.Queue.Pool.Id)/agents?includeCapabilities=true"
(Invoke-RestMethod $Url -UseDefaultCredentials).value.systemCapabilities | Where-Object {
$_
} | ForEach-Object {
try
{
$AgentComputerName = $_.'Agent.ComputerName'
$AgentHomeDirectory = $_.'Agent.HomeDirectory'
MapShare $AgentComputerName $AgentHomeDirectory $PSDrive $Credential
$Path = "\$AgentComputerName$AgentHomeDirectory\.agent".Replace(':', '$')
$AgentBuildDirectoryRoot = (Get-Content $Path | ConvertFrom-Json).workFolder
if ($AgentBuildDirectoryRoot[0] -ne $AgentHomeDirectory[0])
{
Remove-PSDrive $PSDrive -ErrorAction SilentlyContinue
MapShare $AgentComputerName $AgentBuildDirectoryRoot $PSDrive $Credential
}
$Path = "\$AgentComputerName$AgentBuildDirectoryRoot$RelSourceFolderPath".Replace(':', '$')
if (!(Test-Path $Path))
{
return
}
$BuildFolderNumber = (Get-Content $Path | ConvertFrom-Json).agent_builddirectory
$AgentBuildDirectory = [io.path]::GetFullPath("$Path\..\..\..\..$BuildFolderNumber")
& $Action -SystemCapabilities $_ `
-UncAgentBuildDirectory $AgentBuildDirectory `
-AgentBuildDirectory "$AgentBuildDirectoryRoot$LastBuildFolderNumber" `
-Credential $Credential
}
catch
{
$_.Exception
}
finally
{
Remove-PSDrive $PSDrive -ErrorAction SilentlyContinue
}
}
}
我很确定它只适用于本地代理。我会更新我的答案。那些托管在 Azure 中的 运行 代理一开始并不真正需要此功能。
所以我获取了构建定义:
$bd = ...
它有池 ID:
C:\> $bd.queue.pool.id
90
C:\>
现在我可以使用 Url https://myserver.com/tfs/DefaultCollection/_apis/distributedtask/pools/90/agents?includeCapabilities=true
的功能获取池数据我确实得到了很多信息,但是 Agent.BuildDirectory 没有:
C:\> $x = Invoke-RestMethod $Url -UseDefaultCredentials
C:\> $x.value.systemCapabilities[0].PSObject.Properties.Name |? { $_ -match '^Agent' }
Agent.Name
Agent.Version
Agent.ComputerName
Agent.HomeDirectory
Agent.OS
Agent.OSArchitecture
Agent.OSVersion
C:\>
给定一个有效的构建定义,我如何使用其余 API 为与其关联的每个本地代理获取 Agent.BuildDirectory?
如果您从 UI 访问代理的功能,您会发现没有 Agent.BuildDirectory
功能,因此您无法从 REST API 获取它。此外,Agent.BuildDirectory
是代理上的本地路径,其中创建了给定构建管道的所有文件夹,格式类似于 c:\agent_work\_work
,因此构建管道之间是不同的。
您可以从构建管道中获取此变量,或检查构建日志以获取路径。
我最终得到了以下函数:
function Invoke-ForEachBuildAgent(
[Parameter(Mandatory)]$BuildDefinition,
[Parameter(Mandatory)][scriptblock]$Action,
[pscredential]$Credential
)
{
function MapShare($AgentComputerName, $RemoteDirectory, $PSDrive, [pscredential]$Credential)
{
if ($Credential)
{
$Share = "\$AgentComputerName$($RemoteDirectory[0])`$"
$Mapped = $null
try
{
$Mapped = Test-Path $Share
}
catch
{
}
if (!$Mapped)
{
New-PSDrive $PSDrive FileSystem $Share -Credential $Credential > $null
}
}
}
$RelSourceFolderPath = "SourceRootMappinga33a8ed-f8fd-4c08-9f44-440ea9f20315$($BuildDefinition.Id)\SourceFolder.json"
$PSDrive = [guid]::NewGuid().ToString('N')
if (!$Credential -and ($env:USERNAME -ne INSERT_THE_DEFAULT_USER_NAME_HERE))
{
$Credential = Get-Credential -UserName INSERT_THE_DEFAULT_USER_NAME_WITH_DOMAIN_HERE -Message "Login to access the agents"
}
$Url = "$TfsInstanceUrl/_apis/distributedtask/pools/$($BuildDefinition.Queue.Pool.Id)/agents?includeCapabilities=true"
(Invoke-RestMethod $Url -UseDefaultCredentials).value.systemCapabilities | Where-Object {
$_
} | ForEach-Object {
try
{
$AgentComputerName = $_.'Agent.ComputerName'
$AgentHomeDirectory = $_.'Agent.HomeDirectory'
MapShare $AgentComputerName $AgentHomeDirectory $PSDrive $Credential
$Path = "\$AgentComputerName$AgentHomeDirectory\.agent".Replace(':', '$')
$AgentBuildDirectoryRoot = (Get-Content $Path | ConvertFrom-Json).workFolder
if ($AgentBuildDirectoryRoot[0] -ne $AgentHomeDirectory[0])
{
Remove-PSDrive $PSDrive -ErrorAction SilentlyContinue
MapShare $AgentComputerName $AgentBuildDirectoryRoot $PSDrive $Credential
}
$Path = "\$AgentComputerName$AgentBuildDirectoryRoot$RelSourceFolderPath".Replace(':', '$')
if (!(Test-Path $Path))
{
return
}
$BuildFolderNumber = (Get-Content $Path | ConvertFrom-Json).agent_builddirectory
$AgentBuildDirectory = [io.path]::GetFullPath("$Path\..\..\..\..$BuildFolderNumber")
& $Action -SystemCapabilities $_ `
-UncAgentBuildDirectory $AgentBuildDirectory `
-AgentBuildDirectory "$AgentBuildDirectoryRoot$LastBuildFolderNumber" `
-Credential $Credential
}
catch
{
$_.Exception
}
finally
{
Remove-PSDrive $PSDrive -ErrorAction SilentlyContinue
}
}
}
我很确定它只适用于本地代理。我会更新我的答案。那些托管在 Azure 中的 运行 代理一开始并不真正需要此功能。