Can I make a parameter set depend on the value of another parameter?

后端 未结 2 908
北恋
北恋 2021-01-22 09:12

Let\'s say I have a function like:

function Authenticate
{
  param
  (
    [ValidateSet(\'WindowsAuthentication\',\'UsernameAndPassword\')][string] $Authenticati         


        
相关标签:
2条回答
  • 2021-01-22 09:29

    You can do this using DynamicParam. I saw a decent post on this recently here.

    DynamicParam {
        if ($AuthenticationType -eq 'UsernameAndPassword') {
            #create ParameterAttribute Objects for the username and password
            $unAttribute = New-Object System.Management.Automation.ParameterAttribute
            $unAttribute.Mandatory = $true
            $unAttribute.HelpMessage = "Please enter your username:"
            $pwAttribute = New-Object System.Management.Automation.ParameterAttribute
            $pwAttribute.Mandatory = $true
            $pwAttribute.HelpMessage = "Please enter a password:"
    
            #create an attributecollection object for the attributes we just created.
            $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute]
    
            #add our custom attributes
            $attributeCollection.Add($unAttribute)
            $attributeCollection.Add($pwAttribute)
    
            #add our paramater specifying the attribute collection
            $unParam = New-Object System.Management.Automation.RuntimeDefinedParameter('username', [string], $attributeCollection)
            $pwParam = New-Object System.Management.Automation.RuntimeDefinedParameter('password', [string], $attributeCollection)
    
            #expose the name of our parameter
            $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
            $paramDictionary.Add('username', $unParam)
            $paramDictionary.Add('password', $pwParam)
            return $paramDictionary
        }
    }
    
    Process {
        $PSBoundParameters.username
        $PSBoundParameters.password
        }
    
    0 讨论(0)
  • 2021-01-22 09:37

    Using the link from Tim Ferrill's answer, I created the following function to help create dynamic parameters:

    function New-DynamicParameter
    {
        [CmdletBinding(DefaultParameterSetName = 'Core')]    
        param
        (
            [Parameter(Mandatory = $true, ValueFromPipeline = $true)][string] $Name,
            [Parameter(Mandatory = $true, ParameterSetName = 'Core')][Parameter(Mandatory = $true, ParameterSetName = 'ValidateSet')][type] $Type,
            [Parameter(Mandatory = $false)][string] $ParameterSetName = '__AllParameterSets',
            [Parameter(Mandatory = $false)][bool] $Mandatory = $false,
            [Parameter(Mandatory = $false)][int] $Position,
            [Parameter(Mandatory = $false)][bool] $ValueFromPipelineByPropertyName = $false,
            [Parameter(Mandatory = $false)][string] $HelpMessage,
            [Parameter(Mandatory = $true, ParameterSetName = 'ValidateSet')][string[]] $ValidateSet,
            [Parameter(Mandatory = $false, ParameterSetName = 'ValidateSet')][bool] $IgnoreCase = $true
        )
    
        process
        {
            # Define Parameter Attributes
            $ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute
            $ParameterAttribute.ParameterSetName = $ParameterSetName
            $ParameterAttribute.Mandatory = $Mandatory
            $ParameterAttribute.Position = $Position
            $ParameterAttribute.ValueFromPipelineByPropertyName = $ValueFromPipelineByPropertyName
            $ParameterAttribute.HelpMessage = $HelpMessage
    
            # Define Parameter Validation Options if ValidateSet set was used
            if ($PSCmdlet.ParameterSetName -eq 'ValidateSet')
            {
                $ParameterValidateSet = New-Object System.Management.Automation.ValidateSetAttribute -ArgumentList $ValidateSet -Strict (!$IgnoreCase)
            }
    
            # Add Parameter Attributes and ValidateSet to an Attribute Collection
            $AttributeCollection = New-Object Collections.ObjectModel.Collection[System.Attribute]
            $AttributeCollection.Add($ParameterAttribute)
            $AttributeCollection.Add($ParameterValidateSet)
    
            # Add parameter to parameter list
            $Parameter = New-Object System.Management.Automation.RuntimeDefinedParameter -ArgumentList @($Name, $Type, $AttributeCollection)
    
            # Expose parameter to the namespace
            $ParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
            $ParameterDictionary.Add($Name, $Parameter)
            return $ParameterDictionary
        }
    }
    

    And solved my particular problem in the following way:

    function Authenticate
    {
      param
      (
        [ValidateSet('WindowsAuthentication','UsernameAndPassword')][string] $AuthenticationType,
      )
    
      DynamicParam
      {
        if ($AuthenticationType -eq 'UsernameAndPassword')
        {
          New-DynamicParameter Username [string] -Mandatory $true
          New-DynamicParameter Password [string] -Mandatory $true
        }
      }
    
      ...
    }
    

    It became unneeded to have a parameter set when using Dynamic Parameter so I removed the parameter set.

    0 讨论(0)
提交回复
热议问题