PowerShell报错排查:输入错误修正后触发&表达式无效对象问题
PowerShell脚本报错排查与解决:管道元素'&'后无效对象
报错信息
管道元素中'&'后的表达式生成了无效对象。它必须生成命令名称、脚本块或CommandInfo对象。
触发场景
仅在以下特定场景触发:提示用户输入“y或n”时,用户先输入非y/n的错误响应,被重新提示后输入正确的'y'或'n';若用户首次输入正确响应,脚本运行完全正常。
相关代码片段
function SelectUserGui { param( $search ) #Returns a gui window to select user $selection = Get-ADUser -Filter "surname -like '$search'" -Properties * | Select-Object name, samaccountname, DistinguishedName, Enabled, EmployeeID, LockedOut | Out-GridView -PassThru -Title 'Choose a user' if (-not $selection) { Write-Host 'User Not Found / Selection Canceled!!!' -ForegroundColor Red Pause } return $selection } function tryAgain { param( $tryString, $funcName ) $x = Read-Host $tryString if ($x -eq 'y') { & $funcName } elseif ($x -eq 'n') { Clear-Host main } else { Write-Host 'Incorrect entry' -ForegroundColor Red tryAgain $tryString & $funcName } } function disableUser { param ( $aduser ) $ticketNum = Read-Host "`nEnter the ServiceNow Ticket Number" $proceed = Read-Host "`nProceed with disabling for Leave Of Absence? (y or n)" if ($proceed -eq 'y') { Write-Host 'proceeding ...' Write-Host "`n PLEASE ADD FOLLOWING CLOSE NOTES to TICKET $ticketNum :" -ForegroundColor cyan Write-Host "`n Disabled AD account per HR/Workday for LOA `n" -ForegroundColor cyan #$target = $ResultsArray[1][$selection] $aduser = Get-ADUser -Identity $selection.samaccountname -Properties * $prepend = "DISABLED per HR for LOA ($ticketNum) - " $desc = $aduser.description $loaDesc = $prepend + $desc Set-ADUser -Identity $selection.samaccountname -description $loaDesc Disable-ADAccount -Identity $selection.samaccountname Pause #tryAgain } else { Write-Host 'no changes will be made' Pause #tryAgain } } function DisableFunc { Write-Host "`n ***** DISABLE USER UTILITY ***** " -ForegroundColor DarkBlue -BackgroundColor white $search = promptForUser $selection = SelectUserGui $search if ($selection.enabled -eq $True) { Write-Host "`nYou selected user " -NoNewline Write-Host $selection.Name -NoNewline -ForegroundColor Green Write-Host ' with user ID a of ' -NoNewline Write-Host $selection.samAccountName -NoNewline -ForegroundColor Green disableUser $selection } elseif ($selection.enabled -eq $False) { Write-Host "`nUser " -NoNewline Write-Host $selection.Name, '(' -NoNewline -ForegroundColor Yellow Write-Host $selection.samAccountName -NoNewline -ForegroundColor Yellow Write-Host ')' -NoNewline -ForegroundColor Yellow Write-Host ' is already ' -NoNewline Write-Host 'DISABLED' -NoNewline -ForegroundColor Yellow -BackgroundColor Red } $tryString = "`nDisable Another User? (y or n)" $funcName = 'DisableFunc' tryAgain $tryString $funcName }
问题根源
报错核心在tryAgain函数的递归逻辑:
- 当用户输入错误时,递归调用
tryAgain $tryString,未传入第二个参数$funcName,导致递归过程中$funcName变量值为$null。 - 递归调用完成后,又执行
& $funcName,此时$funcName是$null,不符合&操作符要求的命令名称、脚本块或CommandInfo对象类型,因此触发报错。 - 额外问题:递归已经处理了用户的正确输入(执行对应逻辑),后续的
& $funcName会导致重复执行目标函数。
解决方案
修改tryAgain函数,确保递归时传入所有参数,并且移除递归后的多余执行逻辑:
function tryAgain { param( $tryString, $funcName ) $x = Read-Host $tryString if ($x -eq 'y') { & $funcName } elseif ($x -eq 'n') { Clear-Host main } else { Write-Host 'Incorrect entry' -ForegroundColor Red # 递归时传入完整参数,且无需后续再执行& $funcName tryAgain $tryString $funcName } }
补充优化建议
- 可以为
Read-Host的输入做大小写兼容,比如$x = (Read-Host $tryString).ToLower(),避免用户输入大写Y/N导致判断失效。 disableUser函数中直接使用了全局变量$selection,建议改为使用参数$aduser(即$aduser.samaccountname),避免依赖全局变量引发潜在问题。
内容的提问来源于stack exchange,提问作者RookieMistake
相关产品推荐
相关产品推荐

