0

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

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

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

https://docs.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

解决任何这些问题都会有所帮助。提前致谢 :)

4

4 回答 4

2

不是 100% 回答您的问题,但也许它可以帮助您或其他人。

最近,我不得不将用户添加到 AzDo 项目中的团队。我有用户的电子邮件和团队的名称。

我在 AzDo 版本 M183_20210320.1 中使用了以下 Powershell 代码:

$PAT = "my-path"; # get your Personal access token https://docs.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=preview-page
$Headers += @{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($PAT)")) };
 
$Collection = 'my-organisation';
$Project = 'my-project';
$Timeout = 30;
$TeamToAddUser = "my-team-name>";
$EmailToAddToTeam = "my@email.com";
# get project id
$ProjectId = (Invoke-RestMethod -Uri "https://dev.azure.com/$($Collection)/_apis/projects/$($Project)?api-version=6.0" -Method GET -ContentType "application/json;charset=utf-8" -Headers $Headers -TimeoutSec $Timeout).id;
Write-Host "ProjectId: $ProjectId";
# get project descriptor
$ProjecDescriptor = (Invoke-RestMethod -Uri "https://vssps.dev.azure.com/$($Collection)/_apis/graph/descriptors/$($ProjectId)?api-version=6.0-preview" -Method GET -ContentType "application/json;charset=utf-8" -Headers $Headers -TimeoutSec $Timeout).value;
Write-Host "ProjecDescriptor: $ProjecDescriptor";
   
# get all teams in project
$TeamsInProject = (Invoke-RestMethod -Uri "https://vssps.dev.azure.com/$($Collection)/_apis/graph/groups?scopeDescriptor=$($ProjecDescriptor)&api-version=6.0-preview" -Method GET -ContentType "application/json;charset=utf-8" -Headers $Headers -TimeoutSec $Timeout).value;
Write-Host "TeamsInProject: $($TeamsInProject | forEach { "`n - $($_.displayName) : $($_.descriptor)" }) `n";

# get the team 
$Team = $TeamsInProject | Where-Object { $_.displayName -eq $TeamToAddUser }
Write-Host "Team: $($Team.displayName) : $($Team.descriptor)";

# get user id from email
$User = (Invoke-RestMethod -Uri "https://vsaex.dev.azure.com/$($Collection)/_apis/userentitlements?api-version=6.0-preview.3&`$filter=name eq '$(${EmailToAddToTeam})'" -Method GET -ContentType "application/json;charset=utf-8" -Headers $Headers -TimeoutSec $Timeout).members[0];
Write-Host "User to add user: $($User.user.displayName) : $($User.user.originId)";

# add user to team
$body = @{
   "originId" = $User.user.originId
};
$result = (Invoke-RestMethod -Uri "https://vssps.dev.azure.com/$($Collection)/_apis/graph/Users?groupDescriptors=$($Team.descriptor)&api-version=6.0-preview" -Method POST -ContentType "application/json;charset=utf-8" -Headers $Headers -Body $($body | ConvertTo-Json -Depth 10 -Compress) -TimeoutSec $Timeout)
于 2021-03-26T17:45:18.213 回答
2

您可以使用member add api to user 到团队成员。

PUT https://vsaex.dev.azure.com/{organization}/_apis/GroupEntitlements/{groupId}/members/{memberId}?api-version=5.1-preview.1

当您转到Project Settings下的Permissions时,您会发现团队实际上被列为一个组。所以我尝试在上面的 api 中为 groupId 使用团队 ID。它奏效了。

经测试,memeberId其实就是用户id。

您可以通过以下 Get User Entitlements api 获取用户 ID:查看此处了解详细信息。

GET https://vsaex.dev.azure.com/{organization}/_apis/userentitlements?top={top}&skip={skip}&filter={filter}&sortOption={sortOption}&api-version=5.1-preview.2

然后您可以调用上面的 member add api 将用户添加到团队。

$uri ="https://vsaex.dev.azure.com/{ORG}/_apis/GroupEntitlements/{teamid}/members/{userid}?api-version=5.1-preview.1"

$connectionToken="PAT"

$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))

# Invoke the REST call and capture the results (notice this uses the PATCH methodg
$result = Invoke-RestMethod -Uri $group -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method put

如果您无法点击https://vsaex.dev.azure.com。您可能需要检查您的 {PAT} 是否具有执行添加成员操作的所有权限范围。点击此处了解有关 PAT 的更多信息。

缺乏有关 vsaex 的信息。但我猜 vsaex 是用户广告数据的服务器域。由于 Microsoft 在与其他数据不同的服务器中管理用户广告数据信息。

于 2019-11-19T07:24:09.293 回答
2

我最近编写了一个 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 = @("member1@xyz.com", "member2@xyz.com")

#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 }
    }
}

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


如何自己找出正确URLs的:

  • 打开浏览器(我使用 Edge)
  • 按 F12
  • Network
  • 导航到您要观察的事件

在此处输入图像描述

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

在此处输入图像描述

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

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

希望这可以帮助。

于 2019-11-19T06:53:41.213 回答
0

After spending hours to do this via API I found a solution, You can use

POST   https://vssps.dev.azure.com/{organization}/_apis/graph/users?groupDescriptors={groupDescriptor}&api-version=6.0-preview.1

you can add email in a requestbody, JSON will look like

{
  "principalName": "yourmail@goeshere.com"
}

For getting the group descriptor use below GET call

GET https://vssps.dev.azure.com/{organization}/_apis/graph/groups?api-version=6.0-preview.1

Check for group with "displayName" as "{your project name} Team" in the response and take group descriptor of that group.

If you are using Postman to make this call, select basic Auth as authorization and give username empty and password as the PAT token.

于 2021-06-01T12:40:49.153 回答