Search code examples
powershellparameters

Powershell parameter sets in other parameter sets


I have a function with the following parameter requirements:

  1. There are no required parameters
  2. $Credential can optionally be used with any other parameters, or no other parameters
  3. $Title, $Username, and $SearchString cannot be used together
  4. $DefaultObject and $AsPlainText can only be used with $Title or $Username
  5. $DefaultObject and $AsPlainText cannot be used together

Below is what I have so far:

[CmdletBinding(DefaultParameterSetName = 'All')]
param (
    [PSCredential] $Credential,
    [Parameter(ParameterSetName = 'Title')]
    [string] $Title,
    [Parameter(ParameterSetName = 'Username')]
    [string] $Username,
    [Parameter(ParameterSetName = 'Search')]
    [string] $SearchString,
    [Parameter(ParameterSetName = 'Title')]
    [Parameter(ParameterSetName = 'Username')]
    [Parameter(ParameterSetName = 'DefaultObject')]
    [switch] $DefaultObject,
    [Parameter(ParameterSetName = 'Title')]
    [Parameter(ParameterSetName = 'Username')]
    [Parameter(ParameterSetName = 'PlainText')]
    [switch] $AsPlainText
)

I have accomplished items 1-4 on the list, but I am struggling with item 5 to prevent $DefaultObject and $AsPlainText from being called simultaneously. Does anybody know how to prevent them from being used together? I have already tried creating a new ParameterSet for each of them, but that did not work.


Solution

  • Your function's DefaultParameterSetName is 'All', but it is only available when 'none' of the parameters are used, so I expect you need to do some re-thinking about exactly what you are wanting and how it works.

    But, based on what you described, this code should be fairly close to what you want. It is important to understand that you need to use Mandatory to stress that certain parameters are mandatory for certain parameter sets:

    Function Test-Params {
       [CmdletBinding(DefaultParameterSetName = 'All')]
       param (
          [Parameter(Mandatory = $false)]
          [PSCredential] $Credential,
          [Parameter(Mandatory = $true, ParameterSetName = 'Title')]
          [Parameter(Mandatory = $true, ParameterSetName = 'TitleDO')]
          [Parameter(Mandatory = $true, ParameterSetName = 'TitleAPT')]
          [string] $Title,
          [Parameter(Mandatory = $true, ParameterSetName = 'Username')]
          [Parameter(Mandatory = $true, ParameterSetName = 'UsernameDO')]
          [Parameter(Mandatory = $true, ParameterSetName = 'UsernameAPT')]
          [string] $Username,
          [Parameter(Mandatory = $true, ParameterSetName = 'Search')]
          [string] $SearchString,
          [Parameter(Mandatory = $true, ParameterSetName = 'TitleDO')]
          [Parameter(Mandatory = $true, ParameterSetName = 'UsernameDO')]
          [switch] $DefaultObject,
          [Parameter(Mandatory = $true, ParameterSetName = 'TitleAPT')]
          [Parameter(Mandatory = $true, ParameterSetName = 'UsernameAPT')]
          [switch] $AsPlainText
       )
       Write-Host $PSCmdlet.ParameterSetName
       switch ($PSCmdlet.ParameterSetName) {
          'All' {}
          'Title' {}
          'Username' {}
          'TitleDO' {}
          'UsernameDO' {}
          'TitleAPT' {}
          'UsernameAPT' {}
          'Search' {}
          Default {}
       }
    }
    

    These commands work, and comments show host output:

    ## Commands ##                                    ## Write-Host ##
    Test-Params                                        # All
    Test-Params -Title 'MyTitle'                       # Title
    Test-Params -Title 'MyTitle' -DefaultObject        # TitleDO
    Test-Params -Title 'MyTitle' -AsPlainText          # TitleAPT
    Test-Params -Username 'MyUsername'                 # Username
    Test-Params -Username 'MyUsername' -DefaultObject  # UsernameDO
    Test-Params -Username 'MyUsername' -AsPlainText    # UsernameAPT
    Test-Params -SearchString 'My search text'         # Search
    

    But all of these throw errors:

    Test-Params -Title 'MyTitle' -Username 'MyUsername'
    Test-Params -Title 'MyTitle' -SearchString 'My search text'
    Test-Params -Username 'MyUsername' -SearchString 'My search text'
    Test-Params -Title 'MyTitle' -Username 'MyUsername' -SearchString 'My search text'
    Test-Params -SearchString 'My search text' -DefaultObject
    Test-Params -SearchString 'My search text' -AsPlainText