PowerShell/AAD环境下如何通过CSV内邮箱批量查询用户UPN
批量从AAD查询CSV内邮箱对应UPN的脚本修正方案
现有脚本错误排查
- 变量引用错误:ForEach循环的单条对象变量是
$User,但筛选条件里写成了$Users(多了末尾的s),传入的筛选值为空,导致查询失败。 - 逻辑赋值错误:你调用
Get-AzureADUser获取到AAD端的用户数据后,没有把返回结果赋值给变量,反而直接读取本地CSV导入的$User对象的属性——本地CSV仅存储了邮箱地址,不存在UPN、ObjectId、代理地址这些AAD属性,自然拿不到正确结果。 - 匹配规则风险:用
startswith(Mail, 邮箱值)做前缀匹配,可能误命中前缀相同的其他邮箱,比如查询test@domain.com时可能把test1@domain.com也匹配出来。 - 性能缺陷:用
$Result +=的方式逐次追加数组,数据量较大时会反复重建数组对象,运行速度会非常慢。
修正后可直接运行的脚本
# 首次运行前如果没装AzureAD模块,先执行 Install-Module AzureAD -Scope CurrentUser # 执行脚本前先登录AAD:Connect-AzureAD # 导入本地存邮箱的CSV,注意把下方$row.Mail的Mail改成你CSV里存邮箱的实际列名 $localUsers = Import-Csv "C:\Temp\Users.csv" # 用泛型List存结果,比数组追加效率高很多 $results = [System.Collections.Generic.List[PSObject]]::new() foreach ($row in $localUsers) { $targetEmail = $row.Mail.Trim() # 用eq做精确匹配,避免前缀匹配误查 $aadUser = Get-AzureADUser -Filter "Mail eq '$targetEmail'" -ErrorAction SilentlyContinue if (-not $aadUser) { $results.Add([PSCustomObject][ordered]@{ UserName = "无匹配用户" UserPrincipalName = $null PrimarySmtpAddress = $targetEmail AliasSmtpAddresses = $null UserId = $null }) continue } $results.Add([PSCustomObject][ordered]@{ UserName = $aadUser.DisplayName UserPrincipalName = $aadUser.UserPrincipalName PrimarySmtpAddress = $aadUser.Mail AliasSmtpAddresses = ($aadUser.ProxyAddresses | Where-Object { $_ -clike 'smtp:*' } | ForEach-Object { $_ -replace 'smtp:','' }) -join ',' UserId = $aadUser.ObjectId }) } # 导出最终结果 $results | Export-Csv "C:\Temp\output.csv" -NoTypeInformation -Encoding UTF8
大数量场景优化方案
如果你的CSV里邮箱条目超过1000条,逐次调用AAD接口查询效率极低,可以先一次性拉取全量AAD用户到本地内存做哈希匹配,速度能提升10倍以上:
Connect-AzureAD # 一次性拉取全量AAD用户需要的属性,减少不必要的内存占用 $allAadUsers = Get-AzureADUser -All $true | Select-Object DisplayName,UserPrincipalName,Mail,ObjectId,ProxyAddresses # 构建邮箱到用户对象的哈希索引,查询时间复杂度为O(1) $mailIndex = @{} foreach ($user in $allAadUsers) { if ($user.Mail) { $mailIndex[$user.Mail.ToLower()] = $user } } $localUsers = Import-Csv "C:\Temp\Users.csv" $results = [System.Collections.Generic.List[PSObject]]::new() foreach ($row in $localUsers) { $targetEmail = $row.Mail.Trim().ToLower() $aadUser = $mailIndex[$targetEmail] # 后续结果构造逻辑和上面的脚本完全一致即可 }
额外提示
AzureAD模块已经进入官方退役周期,后续长期使用建议迁移到Microsoft Graph PowerShell模块,使用Get-MgUser命令完成同等查询,避免后续模块停止服务后脚本失效。
内容的提问来源于stack exchange,提问作者NickJ76
相关产品推荐
相关产品推荐

