首页 > 解决方案 > Powershell:读取主机以选择数组索引

问题描述

这就是我修改 Powershell 数组的方式:

ForEach ($userID in $usersList) {
    $allUsers += [pscustomobject]@{ID=$usersCounterTable;UserID=$userID;Name=$userInfo.DisplayName;Ext=$userInfo.ipPhone;Cellphone=$userInfo.mobile;Enabled=$isEnabled;VDI=$computerType;Title=$userTitle;}
    $usersCounter += 1
    $usersCounterTable = "[$usersCounter]"
}

稍后在代码中显示表格,我希望用户能够键入一个数字来打开该值,该数字实际上是数组索引/偏移量(减 1)。我无法找到如何做到这一点。

$userID实际上是用户的选择,因为他们也可以输入另一个员工的代码来搜索,或者搜索他的名字。我希望用户能够选择数组索引号。

if (($userID.length -gt 0) -and ($userID.length -lt 5)) {
    $indexNumber = ($userID - 1)
    [????]  $userFinalChoice = $allUsers[$userID].Name  # NOT VALID
}

上面的代码有效,如果用户输入一个介于 1 和 9999 之间的数字......然后我想这样做:($allUsers[$userID]$userID用户使用 Read-Host 选择的数字)。仅,$allUsers[$userID].Name无效,但有效$allUsers[1].Name。如果我能弄清楚这一点,我将能够修复它的其余部分并搜索返回值。

还需要确保用户没有输入超出范围的索引$usersList(使用$ErrorActionPreference = "SilentlyContinue"可能会起作用,因为它只是拒绝搜索拒绝,但它不是那么干净。)

据我了解,我实际上是在寻找 的反面$usersList.IndexOf(‘David’),我想提供索引并返回名称。

非常感谢 - Powershell 初学者。

标签: arrayspowershellindexingoffsetread-host

解决方案


您向我们展示的第一个代码块确实令人困惑,因为您似乎只是从……某处获取用户详细信息,因此无法判断此信息是否确实属于同一用户。

另外,我真的不认为使用格式化表格作为选择菜单是一个好主意,特别是如果列表变大。也许您应该考虑使用列表框构建一个表单,或者Out-GridView按照 Lee_Dailey 的建议使用它。

无论如何,如果你想要它作为控制台菜单,首先确保 ID 号(真的index要选择)以 1 开头

$usersCounter = 1
# collect an array of PsCustomObjects in variable $allUsers
$allUsers = foreach ($userID in $usersList) {
    # don't use $allUsers += , simply output the object
    [PsCustomObject]@{
        ID        = "[$usersCounter]"
        UserID    = $userID
        Name      = $userInfo.DisplayName
        Ext       = $userInfo.ipPhone
        Cellphone = $userInfo.mobile
        Enabled   = $isEnabled
        VDI       = $computerType
        Title     = $userTitle
    }
    $usersCounter++   # increment the counter
}

接下来,将此显示为表格,以便人们可以通过键入“ID”列中显示的数字来选择其中一个用户。循环执行此操作,因此当有人键入有效数字以外的任何内容时,菜单会再次显示。

# start an endless loop
while ($true) {
    Clear-Host
    $allUsers | Format-Table -AutoSize
    $userID = Read-Host "Enter the [ID] number to select a user. Type 0 or Q to quit"
    if ($userID -eq '0' -or $userID -eq 'Q') { break }  # exit from the loop, user quits

    # test if the input is numeric and is in range
    $badInput = $true
    if ($userID -notmatch '\D') {    # if the input does not contain an non-digit
        $index = [int]$userID - 1
        if ($index -ge 0 -and $index -lt $allUsers.Count) {
            $badInput = $false
            # everything OK, you now have the index to do something with the selected user
            # for demo, just write confirmation to the console and exit the loop
            Clear-Host
            Write-Host "You have selected $($allUsers[$index].Name)" -ForegroundColor Green
            break
        }
    }
    # if you received bad input, show a message, wait a couple 
    # of seconds so the message can be read and start over
    if ($badInput) {
        Write-Host "Bad input received. Please type only a valid number from the [ID] column." -ForegroundColor Red
        Start-Sleep -Seconds 4
    }
}

推荐阅读