azure - 如何通过API在Azure Devops中添加团队成员? Groups API 也不起作用

标签 azure azure-devops azure-devops-rest-api azure-rest-api

我是 Azure DevOps 新手,目前正在迁移到它。我想通过 REST API 为我的 azure 项目添加团队成员。我引用了以下文档,但没有提及。 “团队”API 没有向其中添加成员的功能,而只能使用您选择的团队名称创建团队。

https://learn.microsoft.com/en-us/rest/api/azure/devops/?view=azure-devops-rest-5.1

我在 Group Entitlements API 中遇到了另一个问题:

https://learn.microsoft.com/en-us/rest/api/azure/devops/memberentitlementmanagement/group%20entitlements/list?view=azure-devops-rest-5.1

我无法访问此特定 URL:https://vsaex.dev.azure.com。 在其他 API 示例中,他们仅使用了 https://dev.azure.com,这对我来说效果非常好。我不明白 vsaex 代表什么。添加“vsaex”或忽略它也不起作用。我找不到任何与此相关的文档。 用户 API 的 vsaex.dev.azure.com 也会出现同样的问题。

任何这些问题的解决方案都会有所帮助。预先感谢:)

最佳答案

我最近编写了一个 PowerShell 脚本来解决您的第一个问题,但它仅在本地 azure devops 服务器上进行了测试。

class REST {
    #PROPERTIES
    [string]$ContentType = "application/json;charset=utf-8"
    [string]$PAT
    [System.Collections.IDictionary]$Headers
    [string]$Url
    [string]$Collection
    [string]$_Project

    #STATIC PROPERTIES
    static [int]$Timeout = 30

    #CONSTRUCTOR
    REST([string]$PAT, [string]$Url, [string]$Collection, [string]$Project) { $this.Init($PAT, $Url, $Collection, $Project) }
    REST([string]$PAT, [string]$Url, [string]$Collection) { $this.Init($PAT, $Url, $Collection, $null) }
    REST([string]$PAT, [string]$Url) { $this.Init($PAT, $Url, $null, $null) }
    REST([string]$PAT) { $this.Init($PAT, $null, $null, $null) }

    #INITIALIZE
    [void]Init([string]$PAT, [string]$Url, [string]$Collection, [string]$Project) {
        $this.PAT = $PAT
        $this.Url = $Url
        $this.Collection = $Collection
        $this._Project = $Project
        $this.Headers = $(Headers -PAT $PAT) 
    }

    #GET
    [PSCustomObject]Get([string]$Uri) { return Invoke-RestMethod -Uri $Uri -Method GET -ContentType $this.ContentType -Headers $this.Headers -TimeoutSec $([REST]::Timeout) -Verbose }

    #PUT
    [PSCustomObject]Put([string]$Uri, $Body) { return Invoke-RestMethod -Uri $Uri -Method PUT -ContentType $this.ContentType -Headers $this.Headers -Body $Body -TimeoutSec $([REST]::Timeout) -Verbose }

    #POST
    [PSCustomObject]Post([string]$Uri, $Body) { return Invoke-RestMethod -Uri $Uri -Method POST -ContentType $this.ContentType -Headers $this.Headers -Body $Body -TimeoutSec $([REST]::Timeout) -Verbose }

    #DELETE
    [PSCustomObject]Delete([string]$Uri) { return Invoke-RestMethod -Uri $Uri -Method DELETE -ContentType $this.ContentType -Headers $this.Headers -TimeoutSec $([REST]::Timeout) -Verbose }


    #TEAMS
    [PSCustomObject]Teams([string]$Url, [string]$Collection, [string]$Project) { return $($this.Get($(Combine @($Url, $Collection, $Project, "_settings/teams?__rt=fps&__ver=2")))).fps.dataProviders.data.'ms.vss-tfs-web.team-data' }
    [PSCustomObject]Teams([string]$Collection, [string]$Project) { return $this.Teams($this.Url, $Collection, $Project) }
    [PSCustomObject]Teams([string]$Project) { return $this.Teams($this.Url, $this.Collection, $Project) }
    [PSCustomObject]Teams() { return $this.Teams($this.Url, $this.Collection, $this._Project) }

    #TEAM MEMBERS
    [PSCustomObject]TeamMembers([string]$Url, [string]$Collection, [string]$Project, [string]$TeamId) { return $this.Get($(Combine @($Url, $Collection, $Project, "_api/_identity/ReadGroupMembers?__v=5&scope=$($TeamId)&readMembers=true&scopedMembershipQuery=1"))) }
    [PSCustomObject]TeamMembers([string]$Collection, [string]$Project, [string]$TeamId) { return $this.TeamMembers($this.Url, $Collection, $Project, $TeamId) }
    [PSCustomObject]TeamMembers([string]$Project, [string]$TeamId) { return $this.TeamMembers($this.Url, $this.Collection, $Project, $TeamId) }
    [PSCustomObject]TeamMembers([string]$TeamId) { return $this.TeamMembers($this.Url, $this.Collection, $this._Project, $TeamId) }

    #TEAM MEMBER POST
    [PSCustomObject]TeamMemberPost([string]$Url, [string]$Collection, [string]$Project, [string]$TeamId, [string]$Domain, [string]$Name) { $body = '{{''newUsersJson'':''[\''{0}\\\\{1}\'']'',''existingUsersJson'':''[]'',''groupsToJoinJson'':''[\''{2}\'']'',''aadGroupsJson'':''[]''}}' -f ($Domain, $Name, $TeamId); return $this.Post($(Combine @($Url, $Collection, $Project, "_api/_identity/AddIdentities?__v=5")), $body) }
    [PSCustomObject]TeamMemberPost([string]$Collection, [string]$Project, [string]$TeamId, [string]$Domain, [string]$Name) { return $this.TeamMemberPost($this.Url, $Collection, $Project, $TeamId, $Domain, $Name) }
    [PSCustomObject]TeamMemberPost([string]$Project, [string]$TeamId, [string]$Domain, [string]$Name) { return $this.TeamMemberPost($this.Url, $this.Collection, $Project, $TeamId, $Domain, $Name) }
    [PSCustomObject]TeamMemberPost([string]$TeamId, [string]$Domain, [string]$Name) { return $this.TeamMemberPost($this.Url, $this.Collection, $this._Project, $TeamId, $Domain, $Name) }
}

这些是我使用的 REST-API 调用。

  • #TEAMS 以 json 形式返回项目的所有团队。该调用还会为您提供 $TeamId
  • #TEAM MEMBERS 为您提供团队的所有成员
  • #TEAM MEMBER POST 允许您添加新成员。 重要提示:Azure DevOps 必须知道这些成员,这意味着它们需要位于您的域中(我不知道它在 azure DevOps 服务中是如何组织的)
<小时/>

如何使用:(但这与 REST 类在同一个文件中,或者之前将 REST 类作为模块或文件加载)

#ADD = LIST OF VALID AND KNOWN MEMBERS OF YOUR AZURE DEVOPS SERVICE (STORE IT IN A .TXT FILE OR SOMETHING)
$ADD = @("<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3b565e56595e490a7b43424115585456" rel="noreferrer noopener nofollow">[email protected]</a>", "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5538303837302767152d2c2f7b363a38" rel="noreferrer noopener nofollow">[email protected]</a>")

#INITIALIZE REST API
$REST = [REST]::new($PAT, $Uri, $Collection, $Project) #$PAT ~ "atfghfrhfdgdwnx6jnyrculcmaas2g5j6rrogpmn7aza266hrudsahq"; $Uri = https://server.com

#REQUEST TEAMS
$result = $REST.Teams()
$team = $result.team

#REQUEST TEAM MEMBERS
$result = $REST.TeamMembers($team.id)
$members = $result.identities.MailAddress

#ADD MISSING MEMBERS TO TEAM
foreach ($item in $ADD) {

    if (-not $members.Contains($item)) {
        Write-Host "[ps1] add: '$item'" -ForegroundColor Yellow

        #POST ADD MEMBER
        $name = $item.Replace($mail, "")
        $result = $REST.TeamMemberPost($team.id, $domain, $name)
        if ("AddedIdentities" -in $result.PSobject.Properties.Name) { Write-Host "[ps1] successful added: $($result.AddedIdentities.DisplayName) ($($result.AddedIdentities.TeamFoundationId))" -ForegroundColor Green } 
        else { Write-Host "[ps1] fail to add: '$name'" -ForegroundColor Red }
    }
}

我从我的脚本中获取片段。我没有时间测试这些东西,所以请期待错误。

<小时/>

如何自行查找正确的URL:

  • 打开浏览器(我使用的是 Edge)
  • 按 F12
  • 转至网络
  • 导航至您想要观察的事件

enter image description here

  • 清除列表
  • 执行事件(点击按钮)
  • 使用 application/json 查看 GET/POST,如屏幕截图所示:

enter image description here

如果是 GET/POST 事件,您可以在 text 下显示传输的 json

{
  "newUsersJson": "[\"Domain\\\\user\"]",
  "existingUsersJson": "[]",
  "groupsToJoinJson": "[\"2d1dfa03-a108-4421-958a-bdsfdsf161696\"]",
  "aadGroupsJson": "[]"
}

希望这有帮助。

关于azure - 如何通过API在Azure Devops中添加团队成员? Groups API 也不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58916250/

相关文章:

azure - Visual Studio 15.2 上的 ASP.NET Core Web 应用程序 HTTP 错误 502.5 进程失败

python - Azure SDK for Python批量读取blob数据

rest - Azure rest API (6.0-preview.1) Run Pipeline 返回 : "Value cannot be null.\r\nParameter name: runParameters" via postman

asp.net-mvc - 如何在不登录 Azure 门户的情况下从 Azure Web Apps 流式传输日志?

c# - 简单文件传输到 Azure c#

git - 如何将 Visual Studio for Macos 连接到 Azure Devops/VSTS?

azure - VSTS Service Fabric 发布到 Azure : Exception calling ".ctor" with "1" argument(s): "Value cannot be null. Parameter name: authority"

azure-devops - 有没有办法在Azure DevOps中克隆或复制现有的Ci/CD管道

azure-devops-rest-api - 使用 REST API 将构建链接添加到工作项

azure-devops - Azure DevOps Rest Api 是否返回了正确数量的拉取请求?