多个参数集和 PowerShell [英] Multiple parameter sets and PowerShell

查看:45
本文介绍了多个参数集和 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,它将调用一个函数来使用内部工具安排传输.

换句话说,RetainGroupsRemoveFromAllGroups 应该是所有参数集的成员(类似于 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 不能一起使用,但 OldServerNewServer 不再是强制性的.如果我将它们更改为:

 [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)][字符串]$新服务器)}

然后OldServerNewServer 将是强制性的,但RetainGroupsRemoveFromAllGroups 可以一起使用.另外,如果我同时使用retain和remove,那么OldServerNewServer 将成为强制性的,但当它们单独使用时则不是.

我该如何进行这项工作?

解决方案

好的,我想我明白了.您想要的可能组合是:

  1. -RetainGroups
  2. -RemoveFromAllGroups
  3. -RetainGroups 加上 -TransferHomeDrive
  4. -RemoveFromAllGroups 加上 -TransferHomeDrive
  5. -用户名
  6. -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:

  1. -RetainGroups
  2. -RemoveFromAllGroups
  3. -RetainGroups plus -TransferHomeDrive
  4. -RemoveFromAllGroups plus -TransferHomeDrive
  5. Only -UserName
  6. -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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆