Как ввести список строк в качестве параметра? - PullRequest
0 голосов
/ 02 сентября 2018

У меня есть командлет, в котором я принимаю список строк в качестве параметра, определенного в классе c #, например:

[Parameter(Mandatory = true)]
public List<string> AllowedScopes;

Итак, когда я вызываю свою команду с именем Add-Client, как мне предоставить список строк в PowerPhell? Я пробовал это (каждая строка - это другой подход):

-AllowedScopes scope1, scope2, scope3
-AllowedScopes [scope1, scope2, scope3]
-AllowedScopes {scope1, scope2, scope3}
-AllowedScopes {"scope1", "scope2", "scope3"}

Но я всегда просто получаю одну запись в моем списке «AllowedScopes», которая содержит полную строку, введенную после имени параметра AllowedScopes.

Я не могу найти что-нибудь об этом легко, поэтому я думаю, что задаю не тот вопрос.

Конечно, я могу иметь параметр AllowedScopes в виде простой строки и затем сделать что-то вроде этого:

var AllowedScopesAsList = this.AllowedScopes.Split(',').ToList();

Но я думаю, что это должно быть то, что обеспечивается powershell (поскольку он предоставляет множество других полезных функций, не позволяющих мне реализовать всю часть моего командлета, касающуюся взаимодействия с пользователем)

Редактировать: Вот полное содержание моего командлета C # -класса:

using System.Collections.Generic;
using System.Management.Automation;

namespace MyCmdlets
{
    [Cmdlet("Add", "Client")]
    public class AddClient : Cmdlet
    {
        [Parameter(Mandatory = true)]
        public List<string> AllowedScopes;

        protected override void ProcessRecord()
        {
            AllowedScopes.ForEach(a => WriteObject(a));
        }
    }
}

С этим, если я попытаюсь войти в список, как один из ответов сказал:

Add-Client -AllowedScopes @('scope1', 'scope2')

Я получаю этот вывод:

<code><pre>
scope1
scope2

Как и ожидалось.

Но это не работает, если я предоставляю параметр при запросе PowerShell, например:

<code><pre>
PS> <b>Add-Client</b> <kbd>Enter</kbd>

Cmdlet Add-Client at CommandPipelineposition 1
Enter the values for the following parameter:
AllowedScopes[0]: <b>@('scope1','scope2')</b> <kbd>Enter</kbd>
AllowedScopes[1]: <kbd>Enter</kbd>

Теперь вывод такой:

@('scope1','scope2')

Даже если я войду туда по одному, все равно в списке будет только один дочерний элемент:

<code><pre>
AllowedScopes[0]: <b>'scope1'</b>
AllowedScopes[1]: <b>'scope2'</b>
AllowedScopes[2]:

Выход:

<code><pre>
'scope1' 'scope2'

/ edit2: Я загрузил видео, чтобы вы могли увидеть, как powershell ведет себя не так, как ожидалось (по крайней мере, я так думаю):

Youtube-видео с неправильным поведением powershell

Ответы [ 2 ]

0 голосов
/ 02 сентября 2018

Вы, похоже, столкнулись с ошибкой , которая влияет на Windows PowerShell начиная с версии 5.1 и PowerShell Core начиная с версии 6.1.0

Автоматическое приглашение PowerShell неожиданно передает индивидуально введенные элементы для привязки к параметру -AllowedScopes в виде одиночной строки, которая является объединением отдельных элементов, разделенных пробелами.
В отличие от этого, передача массива значений из командной строки - например,
-AllowedScopes scope1, scope2, scope3 - работает правильно.

Ошибка вызвана тем, что ваш параметр определен как List<string>, а не string[]. Возможно, в любом случае string[] является лучшим выбором в этом случае, поэтому обходной путь должен объявить ваш параметр -AllowedScopes как string[] (массив) :

Add-Type -TypeDefinition @'
using System.Collections.Generic;
using System.Management.Automation;

namespace MyCmdlets
{
    [Cmdlet("Add", "Client")]
    public class AddClient : Cmdlet
    {
        [Parameter(Mandatory = true)]
        // Use string[] instead of List<string>
        public string[] AllowedScopes;

        protected override void ProcessRecord()
        {
            foreach (var scope in AllowedScopes) {
                WriteObject(scope);
            }
        }
    }
}
'@ -PassThru | ForEach-Object Assembly | Import-Module

# Let PowerShell prompt for -AllowedScopes
# Due to use of string[] rather than List<string>, the individually entered
# elements are now correctly passed as an array.
Add-Client 

Обратите внимание, что ошибка не появляется, если для общего списка используется тип, отличный от string.


Оригинальный ответ с общей информацией :

Ваш код работает, как задумано, и -AllowedScopes scope1, scope2, scope3 действительно способ передать несколько элементов списка:

scope1, scope2, scope3 использует ,, оператор построения массива, для создания трехэлементного массива, который привязан к параметру -AllowedScopes и преобразован в List<string> экземпляр.

Механизм автоматического запроса PowerShell для обязательных параметров, для которых в командной строке не было передано ни одного аргумента, также работает как задумано:

Для параметра типа набора, такого как -AllowedScopes:

  • элементы коллекции запрашиваются для индивидуально ,
  • и вы сигнализируете о конце ввода, нажимая Введите еще раз после отправки последнего элемента.

Если вы хотите разрешить пользователям передавать все элементы с помощью single , вы должны реализовать собственную логику:

  • Объявите -AllowedScopes как одну строку, чтобы пользователь мог передать что-то вроде
    'scope1, scope2, scope3'

  • Разделить полученное строковое значение на встроенные элементы внутри вашего командлета.

0 голосов
/ 02 сентября 2018

Попробуйте -AllowedScopes @('scope1', 'scope2', 'scope3')

@ конструкция указывает на массив, поэтому @(item,item,item,..) создает массив значений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...