powershell统计ou用户数需确保准确、可复用、覆盖嵌套:一查启用ou直属用户(-searchscope onelevel);二递归统计全子树启用用户(-searchscope subtree,默认);三按命名规范分组聚合;四导出utf8编码csv并加时间戳。

直接用 PowerShell 查每个 OU 下有多少用户,关键不是“数完就完”,而是确保统计准确、可复用、不漏掉嵌套子 OU。核心是用 Get-ADOrganizationalUnit 配合 Get-ADUser 的范围限定,再按需汇总。
一、统计所有启用状态的 OU 及其直属用户数
只查一级 OU(不包含子 OU 中的用户),适合快速掌握顶层结构分布:
- 先获取所有启用的 OU 列表,排除系统默认容器(如 Users、Computers)
- 对每个 OU 执行
Get-ADUser -SearchBase "OU=xxx,DC=..." -Filter {Enabled -eq $true} -ResultSetSize 1并计数,避免全量拉取浪费资源 - 命令示例:
Import-Module ActiveDirectory
Get-ADOrganizationalUnit -Filter {ObjectClass -eq 'organizationalUnit' -and IsCriticalSystemObject -ne $true} |
ForEach-Object {
$ou = $_
$count = (Get-ADUser -SearchBase $ou.DistinguishedName -Filter {Enabled -eq $true} -ResultSetSize 1 -ErrorAction SilentlyContinue).Count
[PSCustomObject]@{
OUName = $ou.Name
DistinguishedName = $ou.DistinguishedName
UserCount = $count
}
} | Sort-Object UserCount -Descending
二、包含子 OU 的递归用户总数(推荐日常使用)
实际管理中更关注“该 OU 及其全部子树下的活跃用户”,这时要用 -SearchScope Subtree(默认值),并注意过滤掉已禁用账号和计算机账户:
-
-SearchScope Subtree是默认行为,无需显式指定,但必须确认 OU 路径正确 - 加
-Filter {Enabled -eq $true}排除禁用账号;-Properties * | Where-Object {$_.ObjectClass -eq 'user'}可进一步保险,不过Get-ADUser默认只返回 user 类对象 - 若只想看前 10 个 OU,结尾加
| Select-Object -First 10
Get-ADOrganizationalUnit -Filter * -Properties CanonicalName |
Where-Object { $_.CanonicalName -notmatch '^builtin|^users|^computers$' } |
ForEach-Object {
$total = (Get-ADUser -SearchBase $_.DistinguishedName -Filter {Enabled -eq $true} -ResultSetSize 5000).Count
[PSCustomObject]@{
OU = $_.Name
Path = $_.CanonicalName
ActiveUsers = $total
}
} | Sort-Object ActiveUsers -Descending
三、按部门或业务线分组统计(结合 OU 命名规范)
如果 OU 命名有规律(例如 “OU=Finance,OU=Departments,DC=corp,DC=local”),可提取层级关键词做聚合:
- 用
Split-Path或正则提取二级 OU 名(如 Departments 下的 Finance、HR) - 用
Group-Object汇总同级 OU 的用户数 - 适合生成月度组织架构报表,或发现某部门账号异常膨胀
$ous = Get-ADOrganizationalUnit -Filter * -SearchBase "OU=Departments,DC=corp,DC=local" -Properties CanonicalName
$ous | ForEach-Object {
$dept = ($_.CanonicalName -split ',')[1].TrimStart('OU=')
$count = (Get-ADUser -SearchBase $_.DistinguishedName -Filter {Enabled -eq $true}).Count
[PSCustomObject]@{Department = $dept; Count = $count}
} | Group-Object Department | ForEach-Object {
[PSCustomObject]@{
Department = $_.Name
TotalUsers = ($_.Group | Measure-Object Count -Sum).Sum
}
}
四、导出为 CSV 并支持后续分析
统计结果存成表格,方便发邮件、贴进 Wiki 或导入 BI 工具:
- 加
Export-Csv时务必用-Encoding UTF8,否则中文 OU 名会乱码 - 建议包含时间戳字段,便于比对历史变化
- 可追加一列标记“是否超阈值”(如 >500 用户触发人工核查)
$report = Get-ADOrganizationalUnit -Filter * |
ForEach-Object {
$c = (Get-ADUser -SearchBase $_.DistinguishedName -Filter {Enabled -eq $true} -ResultSetSize 10000).Count
[PSCustomObject]@{
OUName = $_.Name
DN = $_.DistinguishedName
UserCount = $c
CheckedAt = Get-Date -Format "yyyy-MM-dd HH:mm"
}
}
$report | Export-Csv "C:\Reports\OU_User_Count_$(Get-Date -Format 'yyyyMMdd').csv" -NoTypeInformation -Encoding UTF8











