У меня есть функция со следующими требованиями к параметрам:
$Credential
опционально может использоваться с любыми другими параметрами или без других параметров$Title
, $Username
и $SearchString
нельзя использовать вместе.$DefaultObject
и $AsPlainText
можно использовать только с $Title
или $Username
.$DefaultObject
и $AsPlainText
нельзя использовать вместе.Ниже то, что у меня есть на данный момент:
[CmdletBinding(DefaultParameterSetName = 'All')]
param (
[PSCredential] $Credential,
[Parameter(ParameterSetName = 'Title')]
[string] $Title,
[Parameter(ParameterSetName = 'Username')]
[string] $Username,
[Parameter(ParameterSetName = 'Search')]
[string] $SearchString,
[Parameter(ParameterSetName = 'Title')]
[Parameter(ParameterSetName = 'Username')]
[Parameter(ParameterSetName = 'DefaultObject')]
[switch] $DefaultObject,
[Parameter(ParameterSetName = 'Title')]
[Parameter(ParameterSetName = 'Username')]
[Parameter(ParameterSetName = 'PlainText')]
[switch] $AsPlainText
)
Я выполнил пункты 1–4 в списке, но с пунктом 5 пытаюсь предотвратить одновременный вызов $DefaultObject
и $AsPlainText
. Кто-нибудь знает, как предотвратить их совместное использование? Я уже пытался создать новый набор параметров для каждого из них, но это не сработало.
DefaultParameterSetName вашей функции — «Все», но оно доступно только в том случае, если не используется «ни один» из параметров, поэтому я ожидаю, что вам нужно еще раз подумать о том, чего именно вы хотите и как это работает.
Но, судя по тому, что вы описали, этот код должен быть довольно близок к тому, что вы хотите. Важно понимать, что вам нужно использовать Mandatory
, чтобы подчеркнуть, что определенные параметры являются обязательными для определенных наборов параметров:
Function Test-Params {
[CmdletBinding(DefaultParameterSetName = 'All')]
param (
[Parameter(Mandatory = $false)]
[PSCredential] $Credential,
[Parameter(Mandatory = $true, ParameterSetName = 'Title')]
[Parameter(Mandatory = $true, ParameterSetName = 'TitleDO')]
[Parameter(Mandatory = $true, ParameterSetName = 'TitleAPT')]
[string] $Title,
[Parameter(Mandatory = $true, ParameterSetName = 'Username')]
[Parameter(Mandatory = $true, ParameterSetName = 'UsernameDO')]
[Parameter(Mandatory = $true, ParameterSetName = 'UsernameAPT')]
[string] $Username,
[Parameter(Mandatory = $true, ParameterSetName = 'Search')]
[string] $SearchString,
[Parameter(Mandatory = $true, ParameterSetName = 'TitleDO')]
[Parameter(Mandatory = $true, ParameterSetName = 'UsernameDO')]
[switch] $DefaultObject,
[Parameter(Mandatory = $true, ParameterSetName = 'TitleAPT')]
[Parameter(Mandatory = $true, ParameterSetName = 'UsernameAPT')]
[switch] $AsPlainText
)
Write-Host $PSCmdlet.ParameterSetName
switch ($PSCmdlet.ParameterSetName) {
'All' {}
'Title' {}
'Username' {}
'TitleDO' {}
'UsernameDO' {}
'TitleAPT' {}
'UsernameAPT' {}
'Search' {}
Default {}
}
}
Эти команды работают, а комментарии показывают выходные данные хоста:
## Commands ## ## Write-Host ##
Test-Params # All
Test-Params -Title 'MyTitle' # Title
Test-Params -Title 'MyTitle' -DefaultObject # TitleDO
Test-Params -Title 'MyTitle' -AsPlainText # TitleAPT
Test-Params -Username 'MyUsername' # Username
Test-Params -Username 'MyUsername' -DefaultObject # UsernameDO
Test-Params -Username 'MyUsername' -AsPlainText # UsernameAPT
Test-Params -SearchString 'My search text' # Search
Но все эти ошибки выдают:
Test-Params -Title 'MyTitle' -Username 'MyUsername'
Test-Params -Title 'MyTitle' -SearchString 'My search text'
Test-Params -Username 'MyUsername' -SearchString 'My search text'
Test-Params -Title 'MyTitle' -Username 'MyUsername' -SearchString 'My search text'
Test-Params -SearchString 'My search text' -DefaultObject
Test-Params -SearchString 'My search text' -AsPlainText
Этот работает отлично, большое спасибо. Я не рассматривал возможность создания нескольких наборов для «Имя пользователя» и «Заголовок», но теперь я вижу, что это имеет большой смысл. Кроме того, набор «Все» относится к данным, возвращаемым функцией. Если ни «Заголовок», ни «Имя пользователя» не используются, по умолчанию возвращается все. Спасибо за отличное решение!
@AndrewDraper, пожалуйста. Около года назад я потратил около двух недель свободного времени, просто пытаясь разобраться в том, как работают наборы параметров. Как только вы это поймете, их будет не так уж и сложно сделать, но все равно очень сложно сделать правильно. Начните с одного или двух параметров и заставьте его работать так, как вы хотите, затем добавьте еще один, заставьте его работать, затем добавьте еще один, заставьте его работать и т. д. Из опыта: попытка встроить все параметры в функцию на в то же время это кошмар.
Я считаю, что вам просто нужно проложить путь снаружи внутрь. Вместо добавления наборов параметров в $DefaultObject
добавьте набор параметров к другим нужным наборам:
Function Test {
[CmdletBinding()]
param (
[PSCredential] $Credential,
[Parameter(ParameterSetName = 'DefaultObject')]
[Parameter(ParameterSetName = 'Title')]
[string] $Title,
[Parameter(ParameterSetName = 'DefaultObject')]
[Parameter(ParameterSetName = 'Username')]
[string] $Username,
[Parameter(ParameterSetName = 'Search')]
[string] $SearchString,
[Parameter(ParameterSetName = 'DefaultObject')]
[switch] $DefaultObject,
[Parameter(ParameterSetName = 'Title')]
[Parameter(ParameterSetName = 'Username')]
[Parameter(ParameterSetName = 'PlainText')]
[switch] $AsPlainText
)
}
help test
Производит:
SYNTAX
Test [-Credential <pscredential>] [-Title <string>] [-AsPlainText] [<CommonParameters>]
Test [-Credential <pscredential>] [-Title <string>] [-Username <string>] [-DefaultObject] [<CommonParameters>]
Test [-Credential <pscredential>] [-Username <string>] [-AsPlainText] [<CommonParameters>]
Test [-Credential <pscredential>] [-SearchString <string>] [<CommonParameters>]
Test [-Credential <pscredential>] [-AsPlainText] [<CommonParameters>]
Самый простой способ — просто вычислить
if ($DefaultObject -and $AsPlainText)
, а затем$PSCmdlet.ThrowTerminatingError
в теле вашей функции.