Abraham Zinala
Abraham Zinala

Reputation: 4694

Unable to evaluate against a specific value

I am having trouble thinking of the correct logic on how to go about this. I have a function that accepts two types of switches:

Function Test-Bool {
        
    Param (
        # Input Parameters
        [Parameter(Mandatory = $false,
                   HelpMessage='Enter. Workflow. Name.')]
        [Alias('OMB','MailBox')]
        [string]$Workflow,

        [Parameter(Mandatory = $false)]
        [Alias('EDIPI','DisplayName')]
        [string[]]$UserName

    )

      DynamicParam {
        if ($Workflow -ne $null -and $UserName -ne $null) {
          $parameterAttribute = [System.Management.Automation.ParameterAttribute]@{
              ParameterSetName = "AddingMembers"
              Mandatory = $false
          }

          $attributeCollection = [System.Collections.ObjectModel.Collection[System.Attribute]]::new()
          $attributeCollection.Add($parameterAttribute)

          $dynParam1 = [System.Management.Automation.RuntimeDefinedParameter]::new(
            'Add', [switch], $attributeCollection
          )

          $paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new()
          $paramDictionary.Add('Add', $dynParam1)
          

          $parameterAttribute1 = [System.Management.Automation.ParameterAttribute]@{
              ParameterSetName = "RemovingMembers"
              Mandatory = $false
          }

          $attributeCollection1 = [System.Collections.ObjectModel.Collection[System.Attribute]]::new()
          $attributeCollection1.Add($parameterAttribute1)

          $dynParam11 = [System.Management.Automation.RuntimeDefinedParameter]::new(
            'Remove', [switch], $attributeCollection1
          )

          $paramDictionary.Add('Remove', $dynParam11)
          return $paramDictionary

        }
      }      
    Begin {
        $ABool = {
            'Add Block'
            $Bool = Read-Host -Prompt 'Adding or Removing Member(s)'
                if ($Bool.ToLower() -like 'a*') {
                    $true
                }
                else {
                    Break;
                }
        }
        $RBool = {
            'Remove Block'
            $Bool = Read-Host -Prompt 'Adding or Removing Member(s)'
                if ($Bool.ToLower() -like 'r*') {
                    $true
                }
                else {
                    Break;
                }
        }   
        if ($PSBoundParameters['Add'].IsPresent) { [bool]$Add = $true }
        elseif ($PSBoundParameters['Remove'].IsPresent) { [bool]$Remove = $true }
        elseif (-not$PSBoundParameters['Add'].IsPresent) { $Add = & $ABool }
        elseif (-not$PSBoundParameters['Remove'].IsPresent) { $Remove = & $RBool }
    }
    Process {
        if ($Add) {       
            "Add was selected"
        }
        if ($Remove) {
            "Remove was selected"
        }
    }
}

I can run it several ways:

Which makes sense, because elseif (-not$PSBoundParameters['Add'].IsPresent) { $Add = & $ABool } is evaluated first and when asked, Remove is typed in which throws it into the else block making it Break/Exit.


QUESTION: What can I change to make $Remove be evaluated to true and vise-versa when Add is typed (to make $Add True)?

I honestly confused myself so much that I just decided to post here instead of attempting to figure this out on my own.

Upvotes: 1

Views: 47

Answers (1)

Mathias R. Jessen
Mathias R. Jessen

Reputation: 175085

Use Parameter Sets instead:

Function Test-Bool {
    [CmdletBinding(DefaultParameterSetName = 'Undecided')]
    Param (
        # Input Parameters
        [Parameter(Mandatory = $false,
                   HelpMessage='Enter. Workflow. Name.')]
        [Alias('OMB','MailBox')]
        [string]$Workflow,

        [Parameter(Mandatory = $false)]
        [Alias('EDIPI','DisplayName')]
        [string[]]$UserName,

        [Parameter(Mandatory = $true, ParameterSetName = 'Add')]
        [switch]$Add,

        [Parameter(Mandatory = $true, ParameterSetName = 'Remove')]
        [switch]$Remove
    )

    begin {
        $action = if($PSCmdlet.ParameterSetName -eq 'Undecided'){
            $answer = Read-Host -Prompt 'Adding or Removing Member(s)?'
            if($answer -like 'a*'){
                'Add'
            }
            elseif($answer -like 'r*') {
                'Remove'
            }
            else {
                throw 'Invalid option provided'
            }
        }
        else {
            $PSCmdlet.ParameterSetName
        }

        # $action now contains either 'Add' or 'Remove'
        $actionBlock = @{
            'Add'    = { <# code to add user to workflow #> }
            'Remove' = { <# code to remove user from workflow #> }
        }[$action]
    }

    process {
        # if/else statements no longer needed, $actionBlock contains the correct scriptblock
        . $actionBlock
    }

}

If a user doesn't specify either switch, the parameter set name will be Undecided, and the user will be prompted in the begin block - otherwise we simply use the parameter set name associated with the specified switch.

Since the two switch parameters belong to separate parameter sets, the user can no longer pick both.

Upvotes: 2

Related Questions