Powershell: узел чтения для выбора индекса массива

#arrays #powershell #indexing #offset #read-host

#массивы #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). Only, $allUsers[$userID].Name недопустимо, но $allUsers[1].Name есть. Если я смогу разобраться в этом, я смогу исправить все остальное и выполнить поиск возвращаемого значения.

Также необходимо убедиться, что пользователь не вводит индекс, который выходит за рамки $usersList (использование $ErrorActionPreference = "SilentlyContinue" , вероятно, сработает, поскольку оно просто отклоняет отклонение поиска, но это не так чисто.)

Насколько я понимаю, я на самом деле ищу обратное $usersList.IndexOf(‘David’) , я хочу указать индекс и получить возвращенное имя.

Очень признателен — новичок Powershell.

Комментарии:

1. поскольку вы не показали фактический код, который вы используете, это просто ШУТКА … Read-Host возвращает a [string] . вероятно, вам нужно принудительно ввести пользовательский ввод в качестве [int] .

2. сколько элементов будет в вашем списке? если общее количество достаточно мало, вы можете использовать Out-GridView , чтобы позволить пользователю выбрать элемент для работы.

3. Никогда не знал Out-GridView, но, тем не менее, интересно (целью приложения является скорость, выбор его с помощью мыши сделает операцию слишком долгой), даже если я это понял, я даже не могу заставить код работать жестко = ( (Упс) Я попытаюсь выяснить, как я сделал свой цикл. ReadHost примет идентификатор пользователя (ed12167), например, имя пользователя Eric Dan или местоположение из 6 цифр (650657), в котором перечислены пользователи внутри этого местоположения. Теперь идея состоит в том, чтобы иметь возможность выбирать одного пользователя внутри этого местоположения без необходимости вводить ed12167 или «Eric D» (чтобы ограничить результаты 1 совпадением, чтобы открыть информацию о пользователе)

4. Думал, что это простая вещь, которую я, по-видимому, пропустил, по-видимому, не так просто, хе-хе

5. у меня нет доступа к материалам AD, поэтому у меня нет идей. я вернусь к скрытию … удачи! [ усмешка ]

Ответ №1:

Первый блок кода, который вы нам показываете, действительно сбивает с толку, поскольку вы, похоже, берете данные пользователя просто … где-то, поэтому невозможно сказать, действительно ли эта информация принадлежит одному и тому же пользователю или нет.

Кроме того, я не думаю, что это хорошая идея использовать форматированную таблицу в качестве меню выбора, особенно если список становится большим. Возможно, вам следует подумать о создании формы со списком или использовать Out-GridView для этого, как предложил Lee_Dailey.

В любом случае, если вы хотите использовать его в качестве меню консоли, сначала убедитесь, что идентификационный номер (действительно 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
    }
}