用PowerShell批量替换多文件邮箱为用户账户名的需求及问题
AD组邮箱映射到新域账户名的PowerShell实现
场景说明
我有一批约300个Active Directory(AD)安全组成员导出文件,每个文件存储用户邮箱地址。需要用PowerShell扫描所有文件,通过Get-ADUser cmdlet根据邮箱地址查找新AD域中对应的用户账户名(SamAccountName),并将结果保存到另一个文件夹的同名文件中。
迁移背景:正在将用户访问权限从旧AD域迁移到无信任关系的新AD域,旧域用户账户已修改为包含新域邮箱地址,因此两个域邮箱地址匹配,只能通过邮箱从新域获取新账户名。
优化后的完整代码
# 源文件目录和输出目录 $sourceDir = 'c:\temp\groups\all' $outputDir = 'c:\temp\groups\output' # 确保输出目录存在,不存在则自动创建 if (-not (Test-Path -Path $outputDir)) { New-Item -Path $outputDir -ItemType Directory | Out-Null } # 获取所有目标txt文件 $files = Get-ChildItem -Path $sourceDir -Filter *.txt -File -Recurse foreach ($file in $files) { # 拼接输出文件路径,保持与源文件同名 $outputFile = Join-Path -Path $outputDir -ChildPath $file.Name # 读取邮箱地址、查询账户名并写入输出文件 Get-Content -Path $file.FullName | ForEach-Object { # 跳过空行和空白内容,避免无效查询 if (-not [string]::IsNullOrWhiteSpace($_)) { # 精确匹配邮箱,直接输出账户名字符串 Get-ADUser -Filter "mail -eq '$_'" -Properties mail | Select-Object -ExpandProperty SamAccountName } } | Out-File -Path $outputFile -Encoding utf8 }
关键优化点说明
- 自动创建输出目录:提前检查输出目录是否存在,不存在则创建,避免执行时因目录缺失报错
- 精确匹配邮箱:将原代码的
-Filter {mail -like $_}改为"mail -eq '$_'",邮箱是唯一标识,精确匹配比模糊匹配更高效,也避免误匹配 - 输出干净的账户名:用
-ExpandProperty直接提取SamAccountName的文本值,输出文件中只有纯账户名,而非带属性结构的对象内容 - 过滤无效内容:跳过文件中的空行和空白字符,减少不必要的AD查询请求
- 统一编码:指定
Out-File的编码为utf8,避免不同环境下出现乱码问题
内容的提问来源于stack exchange,提问作者Michal Habala
相关产品推荐
相关产品推荐

