I am building a function which will have three distinct parameter sets, and two of those sets will overlap with the third. The options would look like this:
idtravel | travel | value | status
1 London 600 | Completed
2 NY 1500| Planned
3 Lisbon 150 | Completed
To make it a little more clear, here is a partially completed version the function:
A B
A C
A (D E F)
A B (D E F)
A C (D E F)
The purpose of the function is to automate the process of transferring out an AD account to another location within the company. function Move-AccountOut {
[CmdletBinding(DefaultParameterSetName='NoTransferHomeDrive')]
Param(
[Parameter(Mandatory=$True, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True)]
[string]$Username,
[Parameter(ParameterSetName='RetainGroups')]
[switch]$RetainGroups,
[Parameter(ParameterSetName='RemoveFromAllGroups')]
[switch]$RemoveFromAllGroups,
[Parameter(ParameterSetName='TransferHomeDrive', Mandatory=$False)]
[switch]$TransferHomeDrive,
[Parameter(ParameterSetName='TransferHomeDrive', Mandatory=$True)]
[string]$OldServer,
[Parameter(ParameterSetName='TransferHomeDrive', Mandatory=$True)]
[string]$NewServer
)
}
would automatically retain the users groups when set, and RetainGroups
would automatically remove the user from their groups. The two switches should not be able to be used together. Additionally, if RemoveFromAllGroups
is set, it will call a function to schedule a transfer using an internal tool.
To put it another way, TransferHomeDrive
and RetainGroups
should be a member of all parameter sets (similar to RemoveFromAllGroups
), but should not be able to be used together.
I have tried two ways. The first:
Username
Using this technique, retain and remove cannot be used together, but function Move-AccountOut {
[CmdletBinding(DefaultParameterSetName='NoTransferHomeDrive')]
Param(
[Parameter(Mandatory=$True, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True)]
[string]$Username,
[Parameter(ParameterSetName='RetainGroups')]
[switch]$RetainGroups,
[Parameter(ParameterSetName='RemoveFromAllGroups')]
[switch]$RemoveFromAllGroups,
[Parameter(ParameterSetName='TransferHomeDrive', Mandatory=$False)]
[Parameter(ParameterSetName='RetainGroups')]
[Parameter(ParameterSetName='RemoveFromAllGroups')]
[switch]$TransferHomeDrive,
[Parameter(ParameterSetName='TransferHomeDrive', Mandatory=$True)]
[Parameter(ParameterSetName='RetainGroups')]
[Parameter(ParameterSetName='RemoveFromAllGroups')]
[string]$OldServer,
[Parameter(ParameterSetName='TransferHomeDrive', Mandatory=$True)]
[Parameter(ParameterSetName='RetainGroups')]
[Parameter(ParameterSetName='RemoveFromAllGroups')]
[string]$NewServer
)
}
and OldServer
are no longer mandatory. If I change them to:
NewServer
They will be mandatory, but it no longer cares whether [Parameter(ParameterSetName='TransferHomeDrive', Mandatory=$True)]
[Parameter(ParameterSetName='RetainGroups', Mandatory=$True)]
[string]$OldServer,
[Parameter(ParameterSetName='TransferHomeDrive', Mandatory=$True)]
[Parameter(ParameterSetName='RetainGroups', Mandatory=$True)]
[string]$NewServer
is set.
If I set it up the opposite way:
TransferHomeDrive
Then function Move-AccountOut {
[CmdletBinding(DefaultParameterSetName='NoTransferHomeDrive')]
Param(
[Parameter(Mandatory=$True, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True)]
[string]$Username,
[Parameter(ParameterSetName='RetainGroups')]
[Parameter(ParameterSetName='TransferHomeDrive')]
[switch]$RetainGroups,
[Parameter(ParameterSetName='RemoveFromAllGroups')]
[Parameter(ParameterSetName='TransferHomeDrive')]
[switch]$RemoveFromAllGroups,
[Parameter(ParameterSetName='TransferHomeDrive', Mandatory=$False)]
[switch]$TransferHomeDrive,
[Parameter(ParameterSetName='TransferHomeDrive', Mandatory=$True)]
[string]$OldServer,
[Parameter(ParameterSetName='TransferHomeDrive', Mandatory=$True)]
[string]$NewServer
)
}
and OldServer
will be mandatory, but NewServer
and RetainGroups
can be used together. Additionally, if I use retain and remove together, then RemoveFromAllGroups
and OldServer
become mandatory, but not when they are used on their own.
How do I make this work?
答案 0 :(得分:21)
好的,我想我理解这一点。您想要的可能组合是:
-RetainGroups
-RemoveFromAllGroups
-RetainGroups
加-TransferHomeDrive
-RemoveFromAllGroups
加-TransferHomeDrive
-UserName
-UserName
加-TransferHomeDrive
我假设-OldServer
和-NewServer
仅在移动主驱动器时适用,因此无论何时移动主驱动器,它们都是强制性的。如果不是这样,请告诉我。
所以你在这里有 6个参数集。与powershell的参数设置魔法一样强大,没有一种好的方式可以说"这两个开关是相互排斥的,但也应该在所有参数集中都可用#34;所以你必须多路复用它并用一个或另一个重复每个参数集。
function Move-AccountOut {
[CmdletBinding(DefaultParameterSetName='OnlyUser')]
Param(
[Parameter(
Mandatory=$True,
ValueFromPipeline=$True,
ValueFromPipelineByPropertyName=$True
)]
[string]
$Username,
[Parameter(
Mandatory=$True,
ParameterSetName='RetainOnly'
)]
[Parameter(
Mandatory=$True,
ParameterSetName='RetainAndTransfer'
)]
[switch]
$RetainGroups,
[Parameter(
Mandatory=$True,
ParameterSetName='RemoveOnly'
)]
[Parameter(
Mandatory=$True,
ParameterSetName='RemoveAndTransfer'
)]
[switch]
$RemoveFromAllGroups,
[Parameter(
Mandatory=$True,
ParameterSetName='RetainAndTransfer'
)]
[Parameter(
Mandatory=$True,
ParameterSetName='RemoveAndTransfer'
)]
[Parameter(
Mandatory=$True,
ParameterSetName='TransferOnly'
)]
[switch]
$TransferHomeDrive,
[Parameter(
Mandatory=$True,
ParameterSetName='RetainAndTransfer'
)]
[Parameter(
Mandatory=$True,
ParameterSetName='RemoveAndTransfer'
)]
[Parameter(
Mandatory=$True,
ParameterSetName='TransferOnly'
)]
[string]
$OldServer,
[Parameter(
Mandatory=$True,
ParameterSetName='RetainAndTransfer'
)]
[Parameter(
Mandatory=$True,
ParameterSetName='RemoveAndTransfer'
)]
[Parameter(
Mandatory=$True,
ParameterSetName='TransferOnly'
)]
[string]
$NewServer
)
}
Get-Help Move-AccountOut
的输出:
Move-AccountOut -Username <string> [<CommonParameters>] Move-AccountOut -Username <string> -RetainGroups -TransferHomeDrive -OldServer <string> -NewServer <string> [<CommonParameters>] Move-AccountOut -Username <string> -RetainGroups [<CommonParameters>] Move-AccountOut -Username <string> -RemoveFromAllGroups -TransferHomeDrive -OldServer <string> -NewServer <string> [<CommonParameters>] Move-AccountOut -Username <string> -RemoveFromAllGroups [<CommonParameters>] Move-AccountOut -Username <string> -TransferHomeDrive -OldServer <string> -NewServer <string> [<CommonParameters>]
如果你想让它不那么令人生畏,你可以考虑将remove和retain开关合并为一个参数,如下所示:
[Parameter(
Mandatory=$false # you can leave this out
)]
[ValidateSet(
'None',
'Retain',
'RemoveAll'
)]
[String]
$GroupAction = 'None'
这会将参数集减少到2,并使整个定义看起来像这样:
function Move-AccountOut {
[CmdletBinding(DefaultParameterSetName='OnlyUser')]
Param(
[Parameter(
Mandatory=$True,
ValueFromPipeline=$True,
ValueFromPipelineByPropertyName=$True
)]
[string]
$Username,
[ValidateSet(
'None',
'Retain',
'RemoveAll'
)]
[String]
$GroupAction = 'None' ,
[Parameter(
Mandatory=$True,
ParameterSetName='TransferOnly'
)]
[switch]
$TransferHomeDrive,
[Parameter(
Mandatory=$True,
ParameterSetName='TransferOnly'
)]
[string]
$OldServer,
[Parameter(
Mandatory=$True,
ParameterSetName='TransferOnly'
)]
[string]
$NewServer
)
}
使用以下Get-Help
输出:
Move-AccountOut -Username <string> [-GroupAction <string> {None | Retain | RemoveAll}] [<CommonParameters>] Move-AccountOut -Username <string> -TransferHomeDrive -OldServer <string> -NewServer <string> [-GroupAction <string> {None | Retain | RemoveAll}] [<CommonParameters>]
我想指出的是,虽然定义更简单,但并不意味着它更好。您可能希望优化调用者的参数集,如果这是您计划从shell中交互使用的一个函数,而不是从其他脚本调用(和似乎可能是这种情况)。
因此,在定义中添加一些复杂性以使其更易于使用可能是正确的做法。
答案 1 :(得分:8)
通过添加两个参数集,您可以执行所需的操作。这是必需的,因为你现在有3套,加上一个非设置参数(如果我没记错的话,技术上将它放在__AllParameterSets
集中)。这是4种方法。如果我正确地阅读您的问题,您需要6种方法。您需要以下所有选项:
Move-AccountOut -Username <string> [<CommonParameters>]
Move-AccountOut -Username <string> [-RetainGroups] [-TransferHomeDrive] [-OldServer <string>] [-NewServer <string>] [<CommonParameters>]
Move-AccountOut -Username <string> [-RetainGroups] [<CommonParameters>]
Move-AccountOut -Username <string> [-RemoveFromAllGroups] [-TransferHomeDrive] [-OldServer <string>] [-NewServer <string>] [<CommonParameters>]
Move-AccountOut -Username <string> [-RemoveFromAllGroups] [<CommonParameters>]
Move-AccountOut -Username <string> -OldServer <string> -NewServer <string> [-TransferHomeDrive] [<CommonParameters>]
因此,我们将添加RemoveFromAllGroupsWTran
和RetainGroupsWTran
参数集,将它们添加到$TransferHomeDrive
,$OldServer
和$NewServer
(删除其他相关集)从它们的名称),然后将每个添加到其各自的开关参数。最终看起来像这样:
function Move-AccountOut {
[CmdletBinding(DefaultParameterSetName='NoTransferHomeDrive')]
Param(
[Parameter(Mandatory=$True, ValueFromPipeline=$True, ValueFromPipelineByPropertyName=$True)]
[string]$Username,
[Parameter(ParameterSetName='RetainGroups')]
[Parameter(ParameterSetName='RetainGroupsWTran')]
[switch]$RetainGroups,
[Parameter(ParameterSetName='RemoveFromAllGroups')]
[Parameter(ParameterSetName='RemoveFromAllGroupsWTran')]
[switch]$RemoveFromAllGroups,
[Parameter(ParameterSetName='TransferHomeDrive', Mandatory=$False)]
[Parameter(ParameterSetName='RetainGroupsWTran')]
[Parameter(ParameterSetName='RemoveFromAllGroupsWTran')]
[switch]$TransferHomeDrive,
[Parameter(ParameterSetName='TransferHomeDrive', Mandatory=$True)]
[Parameter(ParameterSetName='RetainGroupsWTran')]
[Parameter(ParameterSetName='RemoveFromAllGroupsWTran')]
[string]$OldServer,
[Parameter(ParameterSetName='TransferHomeDrive', Mandatory=$True)]
[Parameter(ParameterSetName='RetainGroupsWTran')]
[Parameter(ParameterSetName='RemoveFromAllGroupsWTran')]
[string]$NewServer
)
}
答案 2 :(得分:1)
如果在所有参数集中都有两个[ValidateScript()]
参数,并且也只需要一起使用,例如:
Mandatory = false
function SomeFunction {
[CmdletBinding()]
Param(
[Parameter (Mandatory = $true,
ParameterSetName = "A")]
[Parameter (Mandatory = $true,
ParameterSetName = "B")]
[Parameter (Mandatory = $true,
ParameterSetName = "C")]
[switch]$Param1,
[Parameter (Mandatory = $true,
ParameterSetName = "A")]
[switch]$Param2,
[Parameter (Mandatory = $true,
ParameterSetName = "B")]
[string]$Param3,
[Parameter (Mandatory = $true,
ParameterSetName = "C")]
[string]$Param4,
[Parameter (Mandatory = $false,]
[ValidateScript({
if ($Param6) {
$True
}
else {
throw "This parameter will work only with parameter [Param6]"
}
}
)]
[string]$Param5,
[Parameter (Mandatory = $false)]
[ValidateScript({
if ($Param5) {
$True
}
else {
throw "This parameter will work only with parameter [Param5]"
}
}
)]
[string]$Param6
...
}