多个参数集和 PowerShell [英] Multiple parameter sets and PowerShell
问题描述
我正在构建一个具有三个不同参数集的函数,其中两个参数集将与第三个参数集重叠.选项如下所示:
A B交流电A (D E F)A B (D E F)A C (D E F)
为了更清楚一点,这里是一个部分完成的版本:
function Move-AccountOut {[CmdletBinding(DefaultParameterSetName='NoTransferHomeDrive')]参数([参数(强制=$True,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)][字符串]$用户名,[参数(ParameterSetName='RetainGroups')][开关]$RetainGroups,[参数(参数集名称='RemoveFromAllGroups')][开关]$RemoveFromAllGroups,[参数(ParameterSetName='TransferHomeDrive', Mandatory=$False)][开关]$TransferHomeDrive,[参数(ParameterSetName='TransferHomeDrive', Mandatory=$True)][字符串]$OldServer,[参数(ParameterSetName='TransferHomeDrive', Mandatory=$True)][字符串]$新服务器)}
该功能的目的是将 AD 帐户转出到公司内的另一个位置的过程自动化.RetainGroups
会在设置时自动保留用户组,而 RemoveFromAllGroups
会自动将用户从其组中删除.这两个开关应该不能一起使用.此外,如果设置了 TransferHomeDrive
,它将调用一个函数来使用内部工具安排传输.
换句话说,RetainGroups
和 RemoveFromAllGroups
应该是所有参数集的成员(类似于 Username
),但不应该可以一起使用.
我尝试了两种方法.第一个:
function Move-AccountOut {[CmdletBinding(DefaultParameterSetName='NoTransferHomeDrive')]参数([参数(强制=$True,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)][字符串]$用户名,[参数(ParameterSetName='RetainGroups')][开关]$RetainGroups,[参数(参数集名称='RemoveFromAllGroups')][开关]$RemoveFromAllGroups,[参数(ParameterSetName='TransferHomeDrive', Mandatory=$False)][参数(ParameterSetName='RetainGroups')][参数(参数集名称='RemoveFromAllGroups')][开关]$TransferHomeDrive,[参数(ParameterSetName='TransferHomeDrive', Mandatory=$True)][参数(ParameterSetName='RetainGroups')][参数(参数集名称='RemoveFromAllGroups')][字符串]$OldServer,[参数(ParameterSetName='TransferHomeDrive', Mandatory=$True)][参数(ParameterSetName='RetainGroups')][参数(参数集名称='RemoveFromAllGroups')][字符串]$新服务器)}
使用这种技术,retain 和 remove 不能一起使用,但 OldServer
和 NewServer
不再是强制性的.如果我将它们更改为:
[Parameter(ParameterSetName='TransferHomeDrive', Mandatory=$True)][参数(ParameterSetName='RetainGroups', Mandatory=$True)][字符串]$OldServer,[参数(ParameterSetName='TransferHomeDrive', Mandatory=$True)][参数(ParameterSetName='RetainGroups', Mandatory=$True)][字符串]$新服务器
它们将是强制性的,但它不再关心是否设置了 TransferHomeDrive
.
如果我以相反的方式设置:
function Move-AccountOut {[CmdletBinding(DefaultParameterSetName='NoTransferHomeDrive')]参数([参数(强制=$True,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)][字符串]$用户名,[参数(ParameterSetName='RetainGroups')][参数(ParameterSetName='TransferHomeDrive')][开关]$RetainGroups,[参数(ParameterSetName='RemoveFromAllGroups')][参数(ParameterSetName='TransferHomeDrive')][开关]$RemoveFromAllGroups,[参数(ParameterSetName='TransferHomeDrive', Mandatory=$False)][开关]$TransferHomeDrive,[参数(ParameterSetName='TransferHomeDrive', Mandatory=$True)][字符串]$OldServer,[参数(ParameterSetName='TransferHomeDrive', Mandatory=$True)][字符串]$新服务器)}
然后OldServer
和NewServer
将是强制性的,但RetainGroups
和RemoveFromAllGroups
可以一起使用.另外,如果我同时使用retain和remove,那么OldServer
和NewServer
将成为强制性的,但当它们单独使用时则不是.
我该如何进行这项工作?
好的,我想我明白了.您想要的可能组合是:
-RetainGroups
-RemoveFromAllGroups
-RetainGroups
加上-TransferHomeDrive
-RemoveFromAllGroups
加上-TransferHomeDrive
- 仅
-用户名
-UserName
加上-TransferHomeDrive
我假设 -OldServer
和 -NewServer
仅在移动主驱动器时适用,因此无论何时移动主驱动器,它们都是必需的.如果不是这样,请告诉我.
所以你这里有6 个参数集.与 powershell 的参数集魔法一样强大,没有一个好方法可以说这 2 个开关是互斥的,但也应该在所有参数集中可用",因此您必须对其进行多路复用,并用一个或一个重复每个参数集其他.
function Move-AccountOut {[CmdletBinding(DefaultParameterSetName='OnlyUser')]参数([范围(强制=$True,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)][细绳]$用户名,[范围(强制=$True,ParameterSetName='RetainOnly')][范围(强制=$True,ParameterSetName='RetainAndTransfer')][转变]$RetainGroups,[范围(强制=$True,ParameterSetName='RemoveOnly')][范围(强制=$True,ParameterSetName='RemoveAndTransfer')][转变]$RemoveFromAllGroups,[范围(强制=$True,ParameterSetName='RetainAndTransfer')][范围(强制=$True,ParameterSetName='RemoveAndTransfer')][范围(强制=$True,ParameterSetName='TransferOnly')][转变]$TransferHomeDrive,[范围(强制=$True,ParameterSetName='RetainAndTransfer')][范围(强制=$True,ParameterSetName='RemoveAndTransfer')][范围(强制=$True,ParameterSetName='TransferOnly')][细绳]$旧服务器,[范围(强制=$True,ParameterSetName='RetainAndTransfer')][范围(强制=$True,ParameterSetName='RemoveAndTransfer')][范围(强制=$True,ParameterSetName='TransferOnly')][细绳]$新服务器)}
Get-Help Move-AccountOut
的输出:
Move-AccountOut -Username [<通用参数>]Move-AccountOut -用户名<字符串>-RetainGroups -TransferHomeDrive -OldServer ;-新服务器<字符串>[<通用参数>]Move-AccountOut -用户名<字符串>-RetainGroups [<CommonParameters>]Move-AccountOut -用户名<字符串>-RemoveFromAllGroups -TransferHomeDrive -OldServer ;-新服务器<字符串>[<通用参数>]Move-AccountOut -用户名<字符串>-RemoveFromAllGroups [<CommonParameters>]Move-AccountOut -用户名<字符串>-TransferHomeDrive -OldServer ;-新服务器<字符串>[<通用参数>]
简化
如果您想让它不那么令人生畏,您可以考虑将删除和保留开关合并为一个参数,如下所示:
[参数(Mandatory=$false # 你可以省略这个)][验证集('没有任何','保持','移除所有')][细绳]$GroupAction = '无'
这会将您的参数集减少到 2,并使您的整个定义如下所示:
function Move-AccountOut {[CmdletBinding(DefaultParameterSetName='OnlyUser')]参数([范围(强制=$True,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)][细绳]$用户名,[验证集('没有任何','保持','移除所有')][细绳]$GroupAction = '无' ,[范围(强制=$True,ParameterSetName='TransferOnly')][转变]$TransferHomeDrive,[范围(强制=$True,ParameterSetName='TransferOnly')][细绳]$旧服务器,[范围(强制=$True,ParameterSetName='TransferOnly')][细绳]$新服务器)}
使用以下 Get-Help
输出:
Move-AccountOut -Username [-GroupAction <string>{无 |保留 |RemoveAll}] [<CommonParameters>]Move-AccountOut -用户名<字符串>-TransferHomeDrive -OldServer ;-新服务器<字符串>[-GroupAction <string>{无 |保留 |RemoveAll}] [<CommonParameters>]
我确实想指出,虽然 定义 更简单,但这并不意味着它更好.您可能希望为 调用者 优化参数集,如果这是您计划从 shell 以交互方式使用的函数,而不是从其他脚本调用(和似乎是这样).
因此,在定义中添加一些复杂性以使其更易于使用可能是正确的做法.
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:
A B
A C
A (D E F)
A B (D E F)
A C (D E F)
To make it a little more clear, here is a partially completed version the function:
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
)
}
The purpose of the function is to automate the process of transferring out an AD account to another location within the company. RetainGroups
would automatically retain the users groups when set, and RemoveFromAllGroups
would automatically remove the user from their groups. The two switches should not be able to be used together. Additionally, if TransferHomeDrive
is set, it will call a function to schedule a transfer using an internal tool.
To put it another way, RetainGroups
and RemoveFromAllGroups
should be a member of all parameter sets (similar to Username
), but should not be able to be used together.
I have tried two ways. The first:
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
)
}
Using this technique, retain and remove cannot be used together, but OldServer
and NewServer
are no longer mandatory. If I change them to:
[Parameter(ParameterSetName='TransferHomeDrive', Mandatory=$True)]
[Parameter(ParameterSetName='RetainGroups', Mandatory=$True)]
[string]$OldServer,
[Parameter(ParameterSetName='TransferHomeDrive', Mandatory=$True)]
[Parameter(ParameterSetName='RetainGroups', Mandatory=$True)]
[string]$NewServer
They will be mandatory, but it no longer cares whether TransferHomeDrive
is set.
If I set it up the opposite way:
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
)
}
Then OldServer
and NewServer
will be mandatory, but RetainGroups
and RemoveFromAllGroups
can be used together. Additionally, if I use retain and remove together, then OldServer
and NewServer
become mandatory, but not when they are used on their own.
How do I make this work?
Ok, I think I understand this. The possible combinations you want are:
-RetainGroups
-RemoveFromAllGroups
-RetainGroups
plus-TransferHomeDrive
-RemoveFromAllGroups
plus-TransferHomeDrive
- Only
-UserName
-UserName
plus-TransferHomeDrive
I am assuming that -OldServer
and -NewServer
only apply when moving the home drive, so whenever you are moving the home drive, they are mandatory. If that is not the case, let me know.
So what you have here are 6 parameter sets. As powerful as powershell's parameter set magic is, there isn't a good way to say "these 2 switches are mutually exclusive but should also be available in all parameter sets" so you have to multiplex it and repeat every parameter set with one or the other.
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
)
}
The output of 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>]
Simplifying It
If you want to make it less daunting, you might consider consolidating the remove and retain switches into a single parameter, something like this:
[Parameter(
Mandatory=$false # you can leave this out
)]
[ValidateSet(
'None',
'Retain',
'RemoveAll'
)]
[String]
$GroupAction = 'None'
This would reduce your parameter sets down to 2, and make your entire definition look like this:
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
)
}
With the following Get-Help
output:
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>]
I do want to point out that although that's simpler to define that doesn't mean it's better. It may be that you want to optimize your parameter sets for the caller which can be especially important if this is a function you plan on using interactively a lot from the shell, rather than calling from other scripts (and it seems like this may be the case).
So adding some complexity in the definition to make it easier to use might be the right thing to do.
这篇关于多个参数集和 PowerShell的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!