Тут є кілька хороших відповідей, але я хотів зазначити ще пару речей. Параметри функції - це фактично місце, де сяє 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 приймає регулярний вираз, який гарантує, що наданий параметр відповідає тому, що ви очікуєте. Якщо цього немає, викидається інтуїтивний виняток, який точно говорить вам, що не так. Так у цьому прикладі "Щось" спрацювало б добре, але "Літо" не пройшло перевірку.
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"