如何通过Graph SDK高效获取不属于指定20个组的Azure AD用户?
高效获取不属于指定组的Azure AD用户(非Beta版Graph SDK)
方法一:用$filter拼接多组否定条件
在Graph API v1.0中,虽不支持NOT IN语法,但可以通过多个not (memberOf/any(...))条件用and拼接,直接过滤掉属于目标组的用户。针对20个组的规模,这种方式足够高效,无需遍历所有AD组。
C#代码示例:
using Microsoft.Graph; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; public async Task<List<User>> GetUsersNotInExcludedGroupsAsync(GraphServiceClient graphClient, List<string> excludedGroupIds) { // 生成每个组的排除条件 var filterItems = excludedGroupIds.Select(groupId => $"not (memberOf/any(g: g/id eq '{groupId}'))"); // 拼接成完整过滤字符串 var combinedFilter = string.Join(" and ", filterItems); // 发起分页查询,按需指定返回字段减少数据量 var initialResponse = await graphClient.Users .GetAsync(options => { options.QueryParameters.Filter = combinedFilter; options.QueryParameters.Select = new[] { "id", "displayName", "userPrincipalName" }; options.QueryParameters.Top = 999; // 单页最大返回数,可按需调整 }); var resultUsers = new List<User>(); // 处理分页迭代 var pageIterator = PageIterator<User, UserCollectionResponse>.CreatePageIterator( graphClient, initialResponse, user => { resultUsers.Add(user); return true; }); await pageIterator.IterateAsync(); return resultUsers; }
注意:如果拼接后的过滤字符串接近Graph API的查询长度限制(通常为2048字符),可以拆分批次处理——比如先过滤10个组,再在结果中过滤剩下的10个组。
方法二:批量验证用户组归属(适合用户量较小场景)
如果AD用户总数不大,可以先获取全部用户,再通过Graph批量请求验证每个用户是否属于这20个组中的任意一个,最后筛选出不符合条件的用户。
核心步骤:
- 分页获取所有AD用户。
- 构造批量请求,对每个用户调用
/users/{id}/memberOf或/users/{id}/checkMemberGroups接口,验证是否包含目标组ID。 - 根据批量请求结果,过滤掉属于任意目标组的用户。
这种方法避免了过长的过滤字符串,但需要处理更多请求,适合用户规模较小的场景。
方法三:借助Azure AD动态组(长期方案)
如果业务允许且拥有Azure AD Premium P1/P2许可,可以创建动态组,将成员规则设置为(user.objectId not in ['groupId1','groupId2',...,'groupId20'])。动态组会自动维护成员列表,后续只需查询该组的成员即可,无需每次构造复杂过滤条件。
内容的提问来源于stack exchange,提问作者Chris Fellows
相关产品推荐
相关产品推荐

