PowerShell V2: Наборы параметров (ParameterSets)
Одно из великолепных преимуществ Расширенных Функций PowerShell V2 – это простота, с которой вы можете поддерживать parametersets (наборы параметров). ParameterSets – это, действительно, различные НАБОРЫ допустимых параметров. Например, вы можете сказать:
Get-Process -id 0
Get-Process -Name *ss
Это два различных набора параметров для командлета Get-Process. Ниже пример использования наборов параметров с расширенными функциями:
function test-param
{
param(
[Parameter(ParameterSetName="p1",Position=0)]
[DateTime]
$d,
[Parameter(ParameterSetName="p2", Position=0)]
[int]
$i
)
switch ($PsCmdlet.ParameterSetName)
{
"p1" { Write-Host $d; break}
"p2" { Write-Host $i; break}
}
}
Теперь возникает вопрос – какой набор параметров используется? Давайте поэкспериментируем. Очевидно, что вы можете указать, какой параметр вы хотите использовать и результат будет соответствующим:
PS> test-param -d (get-Date)
12/23/2008 3:25:25 PM
PS> test-param -i 42
42
Но что делать, если это нельзя определить однозначно? Вот где начинается волшебство PowerShell. PowerShell использует тип входной информации для определения того, что вы хотите. Если указан тип DateTime, вероятно, требуется использовать набор параметров p1, а если определен тип INT, вероятно, требуется использовать набор параметров p2.
PS> test-param (get-Date)
12/23/2008 3:37:01 PM
PS> test-param 42
42
Таким способом почти всегда достигается требуемый результат, но если нет – всегда можно указать, что требуется (это только механизм помощи вам в работе!).
PS> test-param -d 42
1/1/0001 12:00:00 AM
(Это значение DATETIME, соответствующее 42-м «тикам» часов! Это действительно то, что вы хотели? :-) )
Итак, теперь наступает интересный момент. Что если наборы параметров двусмысленны? Изменим скрипт – сделаем оба параметра строковыми (STRING) и конвертируем их в DATETIME и INT в скрипте соответственно, посмотрим на результат.
function test-param
{
param(
[Parameter(ParameterSetName="p1",Position=0)]
[String]
$d,
[Parameter(ParameterSetName="p2", Position=0)]
[String]
$i
)
switch ($PsCmdlet.ParameterSetName)
{
"p1" { Write-Host ([DateTime]$d); break}
"p2" { Write-Host ([INT]$i); break}
}
}
PS> test-param -i "42"
42
PS> test-param "42"
test-param : Parameter set cannot be resolved using the specified named par
ameters.
At line:1 char:11
+ test-param <<<< "42"
+ CategoryInfo : InvalidArgument: (:) [test-param], Parameter
BindingException
+ FullyQualifiedErrorId : AmbiguousParameterSet,test-param
Если не определить, какой набор параметров необходимо использовать, возникает неопределенность. Но предположим, что, как автор скрипта, вы знаете, что 9 из 10 раз люди хотят использовать набор параметров p2. Вы действительно хотите, чтобы люди указывали имя параметра каждый раз, когда появляется неопределенность? Было бы великолепно, если бы команда PowerShell подумала о такой возможности и предоставила вам механизм определения набора параметров, который будет использоваться в случае неопределенности?
О ДА- они сделали это!
function test-param
{
[CmdletBinding(DefaultParametersetName="p2")]
param(
[Parameter(ParameterSetName="p1",Position=0)]
[String]
$d,
[Parameter(ParameterSetName="p2", Position=0)]
[String]$i
)
switch ($PsCmdlet.ParameterSetName)
{
"p1" { Write-Host ([DateTime]$d); break}
"p2" { Write-Host ([INT]$i); break}
}
}
PS> test-param 42
42
Вечеринка начинается!
Джеффри Сновер (Jeffrey Snover) [MSFT]
Windows Management Partner Architect
Посетите английский блог команды Windows PowerShell: https://blogs.msdn.com/PowerShell
Посетите Windows PowerShell ScriptCenter: https://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx
Перевод: Илья Лушников