PowerShell查询含嵌套结构的AD组成员邮箱的脚本问题排查
问题原因
原脚本无法获取嵌套组邮箱是逻辑bug导致的:
Get-ADGroupMember返回的成员包含用户、组、联系人三类对象,管道直接接Get-ADUser时,非用户对象会被直接过滤,嵌套组本身的mail属性完全不会被读取- 循环内将
$Group变量从CSV行对象直接覆盖为组名字符串,后续读取$Group.'Customer subset'时实际是对字符串取值,永远拿不到合同字段的内容 - 额外性能问题:用
+=逐行追加数组时,PowerShell每次都会重新复制整个数组,成员/组数量大时运行速度会极慢
原脚本用-Recursive参数递归拉取组成员的核心思路是合理的,只需要补全对象类型判断、修复变量bug即可,不需要重构整体逻辑。
修正后可直接运行的脚本
# 提前加载AD模块,避免命令找不到报错 Import-Module ActiveDirectory -ErrorAction Stop # 读取输入CSV,循环中不覆盖原始行对象 $GroupCollection = Import-Csv -Path "C:\Groups.csv" $Report = foreach ($csvRow in $GroupCollection) { $rawGroupName = $csvRow.'OPE DLs' # 处理带@后缀的组名,截取@前的有效标识 if ($rawGroupName -match '@') { $groupIdentity = $rawGroupName.Substring(0, $rawGroupName.IndexOf("@")) } else { $groupIdentity = $rawGroupName } # 递归拉取所有成员,按对象类型收集邮箱 $allMemberMails = Get-ADGroupMember -Identity $groupIdentity -Recursive | ForEach-Object { switch ($_.objectClass) { 'user' { (Get-ADUser -Identity $_.DistinguishedName -Properties mail).mail } 'group' { # 收集嵌套组本身的组邮箱 (Get-ADGroup -Identity $_.DistinguishedName -Properties mail).mail } 'contact' { # 兼容收集外部联系人邮箱 (Get-ADObject -Identity $_.DistinguishedName -Properties mail).mail } } } | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | Sort-Object -Unique if ($allMemberMails.Count -gt 0) { [PSCustomObject]@{ 'Contract Details' = $csvRow.'Customer subset' 'Group Name' = $groupIdentity 'Member Groups' = $allMemberMails -join "`r`n" } } } # 控制台预览结果 $Report | Sort-Object 'Group Name' | Format-Table -AutoSize # 导出CSV,指定UTF8编码避免中文乱码 $Report | Sort-Object 'Group Name' | Export-Csv -Path 'C:\Group-MemberGroups-Report.csv' -NoTypeInformation -Encoding UTF8
优化点说明
- 修复了原脚本的变量覆盖bug,合同详情字段可正常取值
- 补全所有AD对象类型的邮箱收集逻辑,用户、嵌套组、外部联系人的邮箱都会被正常抓取
- 去掉低效的
+=数组拼接逻辑,直接利用foreach管道输出赋值给结果变量,数据量大时性能提升明显 - 增加空值过滤、邮箱去重逻辑,避免无效空行、重复邮箱出现在结果中
- 导出CSV时指定UTF8编码,避免中文、特殊字符乱码
内容的提问来源于stack exchange,提问作者Empty Coder
相关产品推荐
相关产品推荐

