PowerShell脚本问题:为索引分配用户显示名异常求助
问题根源分析
你的脚本出现异常的核心原因是循环逻辑的嵌套错误,以及对需求实现顺序的误解:
- 嵌套循环导致重复输出:在
foreach ($user in $gc)内部,你又写了一个遍历所有索引的for循环,这会导致每处理一个用户,就把所有索引位置都用当前用户的显示名输出一遍——这就是为什么你会看到每个用户对应的所有索引都是同一个名字。 - 逻辑顺序颠倒:你应该先一次性收集所有用户的显示名并建立索引映射,再展示完整的选项列表让用户选择,而不是处理一个用户就输出一次全索引列表。
修正后的脚本实现
下面是重构后的脚本,完美匹配你的需求A/B/C,同时解决了异常问题:
# 步骤A:获取C:\Users下所有唯一的用户文件夹名称 $userFolders = Get-ChildItem C:\Users | Select-Object -ExpandProperty Name # 步骤B:收集每个用户的显示名,构建索引-用户信息映射 $userList = @() foreach ($user in $userFolders) { # 执行Net User命令获取全名 $fullNameOutput = net user $user /domain 2>&1 | Select-String "Full Name" -ErrorAction SilentlyContinue $fullName = $fullNameOutput -replace "Full Name ","" | Out-String -Stream | Trim() # 判断显示名状态 if ($LASTEXITCODE -eq 2) { $displayName = "Account not in ADUC" } elseif ([string]::IsNullOrWhiteSpace($fullName)) { $displayName = "NO DISPLAY NAME in ADUC" } else { $displayName = $fullName } # 添加到用户列表,包含索引(自动按顺序生成)、用户名、显示名 $userList += [PSCustomObject]@{ Index = $userList.Count UserName = $user DisplayName = $displayName } } # 步骤C:展示带索引的完整用户列表 Write-Host "=== 用户索引列表 ===" $userList | ForEach-Object { Write-Host "$($_.Index): $($_.DisplayName)" } # 处理用户选择 $selection = Read-Host "Enter Number(s) (separate with spaces)" $selectedIndices = $selection -split " " | Where-Object { $_ -match '^\d+$' } | ForEach-Object { [int]$_ } # 输出选中的用户信息 Write-Host "`n=== 选中的用户 ===" $userList | Where-Object { $selectedIndices -contains $_.Index } | Select-Object Index, UserName, DisplayName
关键改进点
- 先收集所有用户的显示名,一次性构建完整的索引映射,避免嵌套循环的重复输出问题。
- 使用
PSCustomObject结构化存储用户信息,让索引、用户名、显示名的对应关系更清晰。 - 增加了输入验证,确保用户输入的是有效数字索引。
- 统一处理了各种异常情况(AD中不存在的账户、无显示名的账户)。
测试效果示例
运行后会输出类似这样的列表:
=== 用户索引列表 === 0: Light, Miller 1: Snuffy, Joe 2: Account not in ADUC 3: NO DISPLAY NAME in ADUC Enter Number(s) (separate with spaces): 0 2 === 选中的用户 === Index UserName DisplayName ----- -------- ----------- 0 Light Light, Miller 2 TestUser Account not in ADUC
内容的提问来源于stack exchange,提问作者Abraham Zinala
相关产品推荐
相关产品推荐

