PowerShell单匹配结果时数组异常问题求助
AD用户修改脚本单匹配结果异常问题排查
我编写了一个自动化AD用户账户修改的脚本,用户输入部分姓氏即可匹配查找AD账户。脚本在多匹配、无匹配场景下均正常工作:多匹配时会列出每条结果的对应信息,无匹配时返回“USER NOT FOUND”提示。但仅找到1个匹配结果时会出现异常——用户姓名和UserID会被拆分为单个字符的数组,怀疑是数组构造逻辑存在问题,寻求解决建议。
场景展示
单匹配(异常情况)

多匹配(正常情况)

无匹配(正常情况)

怀疑问题代码段

完整脚本代码
#prompt for last name (or at least portion of last name, then conver to a string with wild card for use in filter $ticketNum = Read-Host "`nEnter the ServiceNow Ticket Number" $lname = Read-Host "`nEnter at least the first three chars of users last name (you may enter full last name)" $search = $lname + "*" #Empty arrays $ResultsArray=@("") $ADUsersList=@("") #add aduser properties to array, return error and exit if no user found $ADUsersList += Get-ADUser -filter 'surname -like $search' -Properties * | select name,samaccountname,DistinguishedName,Enabled if ($ADUsersList.count -le 1){ Write-host "USER NOT FOUND" return } #populate a 2D array with NAM and with UserID $ResultsArray = @(($ADUsersList.name),($ADUsersList.samaccountname),($ADUsersList.enabled)) Write-host "`t NAME `t`t`t USER ID `t`t ACCOUNT ENABLED" #return list of found users and user ids. Preface with index number to use for selection menu for($i=0;$i-le $ResultsArray[0].length-1;$i++){ “[{0}] = {1} `t `t {2} `t `t {3}” -f $i,$ResultsArray[0][$i],$ResultsArray[1] [$i],$ResultsArray[2][$i] } #Prompt $selection = (Read-Host "`nEnter number for user you want to modify") -as [uint32] #Input validation - Only allow a valid index #. If valid, write user selected to screen before proceeding if ($selection -notmatch '^[0-9]+$' -or $selection -gt $ResultsArray[0].length -or $selection -lt 0){ Write-host "INVALID SELECTION!!!" -ForegroundColor Red } else { Write-Host "`nYou selected user " -nonewline Write-Host $ResultsArray[0][$selection] -nonewline -ForegroundColor Green Write-Host " with user ID a of " -nonewline Write-Host $ResultsArray[1][$selection] -nonewline -ForegroundColor Green $proceed = Read-Host "`nProceed with disabling for Leave Of Absence? (y or n)" if($proceed -eq "y"){ Write-Host "proceeding ..." $target = $ResultsArray[1][$selection] $aduser = Get-ADUser -Identity $target -Properties * $prepend = "DISABLED per HR for LOA ($ticketNum) - " $desc = $aduser.description $loaDesc = $prepend + $desc Set-ADUser -Identity $target -description $loaDesc Disable-ADAccount -Identity $target } else{ Write-host "no changes will be made" break } }
问题原因与解决建议
核心问题
- 数组初始化错误:用
$ADUsersList=@("")初始化数组,会导致数组默认包含一个空字符串,后续用+=添加查询结果时,单匹配场景下数组长度为2(空字符串+1个用户),虽不会触发无匹配判断,但会影响属性访问逻辑。 - PowerShell属性访问特性:当集合仅含一个元素时,访问集合属性(如
$ADUsersList.name)不会返回数组,而是直接返回单个字符串。此时将字符串放入数组,会被自动拆分为单个字符的数组,这就是单匹配时的异常根源。 - Filter语法错误:原代码中用单引号包裹filter(
'surname -like $search'),会导致变量$search无法被解析,查询逻辑失效。
解决方案
1. 修正数组初始化与查询逻辑
去掉初始空字符串,直接初始化空数组并赋值查询结果:
# 正确初始化空数组 $ResultsArray = @() $ADUsersList = @() # 修正Filter写法,确保变量被解析 $ADUsersList = Get-ADUser -filter "surname -like '$search'" -Properties * | select name,samaccountname,DistinguishedName,Enabled # 无匹配判断逻辑优化 if ($ADUsersList.Count -eq 0) { Write-host "USER NOT FOUND" return }
2. 强制属性访问返回数组
使用@()强制将属性值转换为数组,避免单元素场景下被拆分为字符:
# 强制转换为数组,保证单匹配时也返回数组类型 $ResultsArray = @( @($ADUsersList.name), @($ADUsersList.samaccountname), @($ADUsersList.Enabled) )
3. 修复语法错误
原代码中$ResultsArray[1] [$i]存在空格,会导致语法错误,需改为$ResultsArray[1][$i]。
4. 可选优化:改用foreach遍历用户列表
放弃二维数组,直接遍历$ADUsersList,代码可读性更高且避免数组相关问题:
Write-host "`t INDEX `t NAME `t`t`t USER ID `t`t ACCOUNT ENABLED" $index = 0 foreach ($user in $ADUsersList) { "[{0}] = {1} `t `t {2} `t `t {3}" -f $index, $user.name, $user.samaccountname, $user.Enabled $index++ }
内容的提问来源于stack exchange,提问作者RookieMistake
相关产品推荐
相关产品推荐

