PowerShell查询未分配职位组的AD用户及代码优化问题
问题分析与优化方案
原脚本存在以下问题,会导致重复结果、逻辑错误及效率低下:
- 用用户名作为匹配依据,AD中可能存在重名用户,引发误判或重复输出
Get-JTGroups函数内每次循环都重置$int=0,若用户属于多个职位组,会重复打印"has JT group"- 遍历每个用户时都重新拉取所有组的成员列表,重复查询AD,效率极低
- 条件判断错误:
if ($int = 0)是赋值操作,而非比较操作if ($int -eq 0)
优化思路
- 用用户SID作为唯一标识,彻底避免重名冲突
- 先一次性收集所有符合条件的职位组的所有成员(递归),存入哈希集(自动去重、查询高效)
- 直接对比用户是否在成员集合中,快速筛选出未分配职位组的用户
- 简化逻辑,减少不必要的循环和冗余输出
优化后的脚本
cls $SearchBase = "OU DN" $ErrorActionPreference = "Stop" # 获取所有排除department的职位组 $jobGroups = Get-ADGroup -SearchBase $SearchBase -Filter 'Name -notlike "*department*"' # 初始化哈希集存储所有职位组的成员SID(自动去重,查询效率高) $groupMembers = [System.Collections.Generic.HashSet[string]]::new() foreach ($group in $jobGroups) { try { # 递归获取组内所有用户成员,提取SID $members = Get-ADGroupMember -Identity $group -Recursive | Where-Object ObjectClass -eq 'user' foreach ($member in $members) { # 加入哈希集,自动忽略重复项 [void]$groupMembers.Add($member.SID.Value) } } catch { Write-Warning "处理组 $($group.Name) 时出错: $($_.Exception.Message)" } } # 获取目标OU下所有用户 $allUsers = Get-ADUser -SearchBase $SearchBase -Filter * -Properties Name # 筛选未在任何职位组中的用户 $usersWithoutJobGroups = $allUsers | Where-Object { -not $groupMembers.Contains($_.SID.Value) } # 输出结果 Write-Host "`n===== 未分配任何职位组的用户 =====" $usersWithoutJobGroups | ForEach-Object { Write-Host $_.Name } Write-Host "`n总计: $($usersWithoutJobGroups.Count) 个用户"
优化点说明
- 使用
HashSet存储成员SID,自动去重且查询时间复杂度为O(1),大幅提升效率 - 一次性拉取所有组的成员,避免每个用户都重复查询AD
- 用用户SID唯一标识,彻底解决重名导致的重复或误判问题
- 修正条件判断逻辑,输出更简洁,只展示需要的结果
- 增加错误处理,用
Write-Warning提示异常,不中断整个脚本执行
内容的提问来源于stack exchange,提问作者Assen Antonov
相关产品推荐
相关产品推荐

