Multiple parameter sets and PowerShell

后端 未结 3 582
感动是毒
感动是毒 2020-12-29 05:44

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:



        
3条回答
  •  温柔的废话
    2020-12-29 06:03

    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   []
    
    Move-AccountOut -Username  -RetainGroups -TransferHomeDrive -OldServer  -NewServer   []
    
    Move-AccountOut -Username  -RetainGroups  []
    
    Move-AccountOut -Username  -RemoveFromAllGroups -TransferHomeDrive -OldServer  -NewServer   []
    
    Move-AccountOut -Username  -RemoveFromAllGroups  []
    
    Move-AccountOut -Username  -TransferHomeDrive -OldServer  -NewServer   []
    

    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  [-GroupAction  {None | Retain | RemoveAll}]  []
    
    Move-AccountOut -Username  -TransferHomeDrive -OldServer  -NewServer  [-GroupAction  {None | Retain | RemoveAll}]  [] 
    

    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.

提交回复
热议问题