Как определить, было ли указано значение параметра командлета PowerShell?

В PowerShell 1.0, если у меня есть параметр командлета типа enum, какой метод рекомендуется использовать для проверки того, указал ли пользователь этот параметр в командной строке командлета? Например:

MyEnum : int { No = 0, Yes = 1, MaybeSo = 2 }

class DoSomethingCommand : PSCmdlet
...
private MyEnum isEnabled;

[Parameter(Mandatory = false)]
public MyEnum IsEnabled
{
    get { return isEnabled; }
    set { isEnabled = value; }
}

protected override void ProcessRecord()
{
    // How do I know if the user passed -IsEnabled <value> to the cmdlet?
}

Есть ли способ сделать это без необходимости заполнения isEnabled фиктивным значением? По умолчанию он будет равен 0, и я не хочу заполнять каждый параметр или добавлять фиктивное значение в мое перечисление. У меня потенциально есть много командлетов с сотнями параметров, должен быть лучший способ. Это связано с этим вопросом, но я искал более чистый способ сделать это. Спасибо.


person Jack Straw    schedule 29.07.2009    source источник
comment
@Jack Straw Если у вас потенциально есть много командлетов с сотнями параметров, вы можете рассмотреть возможность разделения некоторых из этих функций. Одним из ключевых преимуществ PowerShell является возможность обнаружения, а наличие большого количества параметров значительно усложняет самообнаружение.   -  person Steven Murawski    schedule 30.07.2009
comment
@Стивен, извините, я, возможно, ввел в заблуждение - не каждый командлет имеет сотни параметров :), а многие командлеты, которые приводят к множеству параметров. Спасибо за ваш комментарий.   -  person Jack Straw    schedule 30.07.2009
comment
@RezaAghaei Лучше также указать то, что вы делаете в своем комментарии, на случай, если вы позже удалите свой пост в блоге. В этом случае код$PSBoundParameters.ContainsKey("paramater name") можно использовать для проверки того, был ли указан параметр.   -  person Dave F    schedule 27.12.2018
comment
@DaveF Я вижу, что другой ответ коротко указывает на то же решение. Во всяком случае, я добавил здесь краткое изложение сообщения в блоге в качестве ответа, включая пример.   -  person Reza Aghaei    schedule 27.12.2018


Ответы (6)


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

[Parameter(Mandatory = false)]
public MyEnum? IsEnabled { get; set; }

Обратите внимание ? модификатор на MyEnum. Затем вы можете проверить, установлено ли оно так:

if (this.IsEnabled.HasValue) { ... }
person Community    schedule 31.07.2009
comment
Это именно то, что я искал. Спасибо. На самом деле я сделал локальную переменную, а не свойство нулевым типом, который также работает. - person Jack Straw; 04.08.2009

Помимо PowerShell, никогда не стоит использовать 0 таким образом. Вы всегда должны использовать 0 для наиболее подходящего значения по умолчанию. В этом случае наиболее подходящим значением по умолчанию должно быть что-то вроде «Не установлено».

В конечном счете, это не имеет ничего общего с PowerShell, а связано только с хорошей практикой написания кода для .NET.

  • Ойсин
person x0n    schedule 30.07.2009
comment
@x0n: Спасибо за ответ. Вопрос о том, использовать ли 0 для значений перечисления или нет, является спорным вопросом, но в любом случае мой существующий продукт имеет много значений 0 для перечислений. Я предполагаю, что мой более широкий вопрос заключается в том, что разработчики шаблонов командлетов используют в этой ситуации? Использовать «неуказанное» значение по умолчанию для каждого параметра и проверять его перед применением значений параметра к объекту в ProcessRecord()? Это может стать немного громоздким для больших продуктов со многими типами параметров. - person Jack Straw; 30.07.2009
comment
В v2.0 powershell было добавлено новое свойство: this.MyInvocation.BoundParameters, где это PSCmdlet. Это хэш-таблица пар ключ/значение имен и значений параметров, которые были привязаны к командлету. Если ваше перечисление было указано, оно будет в этом словаре. Если он дефолт, то его там не будет. Я не знаю ничего, кроме взлома строк, который сделает то же самое в версии 1.0. - person x0n; 03.08.2009
comment
x0n, спасибо, я видел это свойство 2.0. К сожалению, сейчас мне нужно кодировать против 1.0. Я думаю, что приведенный ниже ответ Кейта с использованием обнуляемой оболочки - это именно то, что я ищу. - person Jack Straw; 04.08.2009

Как вариант, вы можете использовать коллекцию $PSBoundParameters, чтобы проверить, передается ли методу.

Предположим, у нас есть файл json, подобный следующему { "p1": "value1", "p2": "value2" }, и мы хотим создать функцию, которая принимает параметры p1 и p2 и обновляет значения p1 и p2 в файле, если они передаются функции. Предположим, что эти значения могут быть null и иметь эти значения как нулевые не эквивалентно тому, чтобы не передавать их.

Например, Update-Values -p1 $null должен обновить p1 до null и не должен изменять p2.

Для этого мы должны иметь возможность определить, был ли параметр передан методу или нет.

Пример. Как определить, передан ли параметр для необязательного параметра, который может принимать null в качестве значения?

Function Update-Values ($p1, $p2) {
    If($PSBoundParameters.ContainsKey("p1")) {
        Write-Host "p1 passed"
    }
    else {
        Write-Host "p1 not passed"
    }
    If($PSBoundParameters.ContainsKey("p2")) {
        Write-Host "p2 passed"
    }
    else {
        Write-Host "p2 not passed"
    }
}

Затем, если вы запустите функцию, используя следующий параметр:

Update-Values -p1 $null
# Update-Values -p1 "something"

В результате вы увидите:

p1 passed
p2 not passed

Вы можете прочитать сообщение в блоге здесь: Как определить, передается ли параметр командлету Powershell.

person Reza Aghaei    schedule 27.12.2018

Я знаю, что этот поток немного устарел, но лучший способ сделать это — объявить свой параметр, используя тип SwitchParameter. Тогда вашим пользователям не нужно будет передавать -IsEnabled , они просто добавят что-то вроде -Enabled в качестве параметра.

Затем вы проверяете свойство .IsPresent вашего параметра, чтобы увидеть, добавил ли вызывающий объект -Enabled к вызову командлета.

person Darren Gosbell    schedule 30.09.2009
comment
@Darren: это определенно работает для логических параметров, но я искал решение для необязательных небулевых параметров. Тип с нулевым значением работает хорошо. Конечно, PS v2 теперь имеет словарь параметров, доступных в командлете, так что, вероятно, это правильный путь. Спасибо. - person Jack Straw; 06.10.2009

Единственное, что я вижу, это изменить ваше перечисление, чтобы значение 0 называлось Unknown или что-то в этом роде.

Проблема в том, что перечисления — это просто целые числа в фоновом режиме, а целые числа — это типы значений. Неблагоприятным последствием является то, что они должны иметь значение, и это значение по умолчанию равно 0.

person Josip Medved    schedule 30.07.2009

person    schedule
comment
Обратите внимание, что это неправильно работает с позиционными параметрами. Они не находятся по имени в BoundParameters, но указаны и имеют значение. - person oɔɯǝɹ; 05.05.2015