Здесь есть несколько хороших ответов, но я хотел бы отметить несколько других вещей. Параметры функций - это место, где светит PowerShell. Например, вы можете иметь именованные или позиционные параметры в расширенных функциях, например:
function Get-Something
{
Param
(
[Parameter(Mandatory=$true, Position=0)]
[string] $Name,
[Parameter(Mandatory=$true, Position=1)]
[int] $Id
)
}
Затем вы можете либо вызвать его, указав имя параметра, либо просто использовать позиционные параметры, поскольку вы явно их определили. Так что любой из них будет работать:
Get-Something -Id 34 -Name "Blah"
Get-Something "Blah" 34
Первый пример работает, хотя Name
предоставляется второй, потому что мы явно использовали имя параметра. Второй пример работает в зависимости от позиции, поэтому Name
должен быть первым. Когда это возможно, я всегда стараюсь определить позиции, чтобы оба варианта были доступны.
PowerShell также имеет возможность определять наборы параметров. Это использует это вместо перегрузки метода, и снова довольно полезно:
function Get-Something
{
[CmdletBinding(DefaultParameterSetName='Name')]
Param
(
[Parameter(Mandatory=$true, Position=0, ParameterSetName='Name')]
[string] $Name,
[Parameter(Mandatory=$true, Position=0, ParameterSetName='Id')]
[int] $Id
)
}
Теперь функция будет либо принимать имя, либо идентификатор, но не оба. Вы можете использовать их по месту или по имени. Так как они другого типа, PowerShell поймет это. Так что все это будет работать:
Get-Something "some name"
Get-Something 23
Get-Something -Name "some name"
Get-Something -Id 23
Вы также можете назначить дополнительные параметры для различных наборов параметров. (Это был довольно простой пример.) Внутри функции вы можете определить, какой набор параметров использовался с помощью свойства $ PsCmdlet.ParameterSetName. Например:
if($PsCmdlet.ParameterSetName -eq "Name")
{
Write-Host "Doing something with name here"
}
Затем, на смежном примечании, есть также проверка параметров в PowerShell. Это одна из моих любимых функций PowerShell, и она делает код внутри ваших функций очень чистым. Есть множество проверок, которые вы можете использовать. Несколько примеров:
function Get-Something
{
Param
(
[Parameter(Mandatory=$true, Position=0)]
[ValidatePattern('^Some.*')]
[string] $Name,
[Parameter(Mandatory=$true, Position=1)]
[ValidateRange(10,100)]
[int] $Id
)
}
В первом примере ValidatePattern принимает регулярное выражение, которое гарантирует, что предоставленный параметр соответствует ожидаемому. Если это не так, выдается интуитивно понятное исключение, которое говорит вам, что именно не так. Таким образом, в этом примере «Something» будет работать нормально, но «Summer» не пройдет проверку.
ValidateRange гарантирует, что значение параметра находится в диапазоне, который вы ожидаете для целого числа. Таким образом, 10 или 99 сработают, но 101 сгенерирует исключение.
Еще одним полезным является ValidateSet, который позволяет явно определять массив допустимых значений. Если будет введено что-то еще, будет сгенерировано исключение. Есть и другие, но, вероятно, наиболее полезным является ValidateScript. Для этого требуется блок скрипта, который должен иметь значение $ true, поэтому пределом является небо. Например:
function Get-Something
{
Param
(
[Parameter(Mandatory=$true, Position=0)]
[ValidateScript({ Test-Path $_ -PathType 'Leaf' })]
[ValidateScript({ (Get-Item $_ | select -Expand Extension) -eq ".csv" })]
[string] $Path
)
}
В этом примере мы уверены, что не только $ Path существует, но и что это файл (в отличие от каталога) и имеет расширение .csv. ($ _ относится к параметру, находящемуся внутри вашего скриптового блока.) Вы также можете передать гораздо большие многострочные скриптовые блоки, если требуется этот уровень, или использовать несколько скриптовых блоков, как я сделал здесь. Это чрезвычайно полезно и делает для хороших чистых функций и интуитивных исключений.
Test "ABC" "DEF"