Powershell:多个参数集

Rya*_*anL 19 powershell

我正在构建一个具有3个不同参数集的函数,其中2个与第3个集重叠.选项看起来像这样:

A B
A C
A (D E F)
A B (D E F)
A C (D E F)
Run Code Online (Sandbox Code Playgroud)

为了使它更清晰,这里是一个部分完成的版本功能:

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
    )
}
Run Code Online (Sandbox Code Playgroud)

该功能的目的是自动化将AD帐户转出到公司内的其他位置的过程.RetainGroups将在设置时自动保留用户组,RemoveFromAllGroups将自动从其组中删除用户.两个开关不能一起使用.此外,如果TransferHomeDrive设置,它将调用一个函数来使用内部工具安排传输.

换一种方式,RetainGroupsRemoveFromAllGroups应该是所有参数集(类似于成员Username),但不应该是能够一起使用.

我试过两种方法.首先:

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
    )
}
Run Code Online (Sandbox Code Playgroud)

使用这种技术,保留和删除不能一起使用,但OldServerNewServer不再是强制性的.如果我将它们改为:

        [Parameter(ParameterSetName='TransferHomeDrive', Mandatory=$True)]
        [Parameter(ParameterSetName='RetainGroups', Mandatory=$True)]
        [string]$OldServer,

        [Parameter(ParameterSetName='TransferHomeDrive', Mandatory=$True)]
        [Parameter(ParameterSetName='RetainGroups', Mandatory=$True)]
        [string]$NewServer
Run Code Online (Sandbox Code Playgroud)

它们是强制性的,但它不再关心是否TransferHomeDrive已设定.

如果我以相反的方式设置它:

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
    )
}
Run Code Online (Sandbox Code Playgroud)

然后,OldServerNewServer将是强制性的,但RetainGroupsRemoveFromAllGroups可以一起使用.另外,如果我使用保留和删除在一起,然后OldServerNewServer成为强制性的,而不是在他们自己使用.

有关如何使这项工作的任何建议?

bri*_*ist 22

好的,我想我理解这一点.您想要的可能组合是:

  1. -RetainGroups
  2. -RemoveFromAllGroups
  3. -RetainGroups-TransferHomeDrive
  4. -RemoveFromAllGroups-TransferHomeDrive
  5. 只要 -UserName
  6. -UserName-TransferHomeDrive

我假设-OldServer并且-NewServer仅在移动主驱动器时适用,所以无论何时移动主驱动器,它们都是强制性的.如果不是这样,请告诉我.

所以你在这里有6个参数集.与powershell的参数设置魔法一样强大,没有一种好方法可以说"这两个开关是互斥的,但也应该在所有参数集中都可用",所以你必须多路复用它并用一个或者重复每个参数集.其他.

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
)

}
Run Code Online (Sandbox Code Playgroud)

输出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>]
Run Code Online (Sandbox Code Playgroud)

简化它

如果你想让它不那么令人生畏,你可以考虑将remove和retain开关合并为一个参数,如下所示:

[Parameter(
    Mandatory=$false # you can leave this out
)]
[ValidateSet(
    'None',
    'Retain',
    'RemoveAll'
)]
[String]
$GroupAction = 'None'
Run Code Online (Sandbox Code Playgroud)

这会将参数集减少到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
)

}
Run Code Online (Sandbox Code Playgroud)

使用以下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>] 
Run Code Online (Sandbox Code Playgroud)

我想指出的是,尽管定义更简单并不意味着它更好.您可能希望为调用者优化参数集,如果这是一个您计划从shell中交互使用的函数,而不是从其他脚本调用(这似乎可能是案件).

因此,在定义中添加一些复杂性以使其更易于使用可能是正确的做法.

  • 这是我在网上看到的PowerShell参数集的最佳解释.这个答案比标准的MSDN页面要好得多. (3认同)

The*_*ian 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>]
Run Code Online (Sandbox Code Playgroud)

因此,我们将添加RemoveFromAllGroupsWTranRetainGroupsWTran参数集,将它们添加到$TransferHomeDrive,, $OldServer$NewServer(从中删除其他相关的集名称),然后将每个添加到其各自的switch参数.最终看起来像这样:

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
    )
}
Run Code Online (Sandbox Code Playgroud)