You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Azure DevOps REST API获取指定组/团队的成员列表

Azure DevOps 审批组成员邮箱获取实现方案

核心问题说明

你之前只能查到组基础信息、拿不到成员,核心原因有两个:一是没有用对GraphHttpClient的对应成员查询接口,二是大概率没从Service Hook payload里取到正确的组描述符(descriptor),或者权限配置不全。

具体实现步骤

  • 第一步:提取正确的组标识
    Service Hook在流水线进入待审批状态时推送的payload中,审批组的唯一标识descriptor存放在approvals[].approverGroups[].descriptor路径下,不要用组名、组显示ID去查,必须用这个descriptor作为查询入参。
  • 第二步:配置正确的接口权限
    调用接口使用的PAT或者服务主体,必须开通Graph 读取权限,同时在对应项目中至少拥有Reader角色,权限不足时接口不会直接返回403错误,只会返回空的成员列表,是高频踩坑点。
  • 第三步:调用GraphHttpClient拉取成员列表
    不要调用组基础详情接口,直接用ListMembershipAsync方法查询组成员关系,查询方向设为向下遍历,遍历深度设为1即可拿到直属成员,如果你的审批组存在嵌套组,可把深度调大,或者对返回的组类型节点递归查询。
  • 第四步:批量获取成员邮箱
    拿到成员的descriptor列表后,调用ListUsersAsync批量查询用户详情,返回对象中的MailAddress字段就是对应用户的邮箱地址,不要逐个单用户查询,批量接口性能更好。

参考实现代码

// 初始化Azure DevOps连接
using var connection = new VssConnection(
    new Uri("你的Azure DevOps组织服务地址,例如https://dev.azure.com/your-org"),
    new VssBasicCredential(string.Empty, "你的PAT令牌")
);
var graphClient = connection.GetClient<GraphHttpClient>();

// 替换为从Service Hook payload中提取的审批组descriptor
var targetGroupDescriptor = "从钩子消息中拿到的审批组descriptor";

// 查询组下直属成员关系
var memberships = await graphClient.ListMembershipsAsync(
    subjectDescriptor: targetGroupDescriptor,
    direction: GraphTraversalDirection.Down,
    depth: 1
);

// 提取所有成员的descriptor
var memberDescriptors = memberships.Select(m => m.MemberDescriptor).ToList();

// 批量查询用户信息,提取邮箱列表
var users = await graphClient.ListUsersAsync(identifiers: memberDescriptors);
var approverEmails = users
    .Where(u => u.SubjectKind == "User") // 过滤掉嵌套组节点
    .Select(u => u.MailAddress)
    .ToList();

// 如果需要处理嵌套组,对SubjectKind为Group的节点,递归调用上面的成员查询逻辑即可

注意事项

  • 不要使用已标记弃用的IdentityHttpClient接口查询成员,该接口返回的身份信息字段不全,很多时候不会返回最新的用户邮箱。
  • 如果你的审批组配置了AAD安全组,上述逻辑同样适用,GraphHttpClient会自动解析AAD组下的成员信息,不需要额外调用AAD接口。

内容的提问来源于stack exchange,提问作者asimian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 02:54:19