Parameter Set question

Welcome Forums General PowerShell Q&A Parameter Set question

Viewing 7 reply threads
  • Author
    Posts
    • #229855
      Participant
      Topics: 7
      Replies: 9
      Points: 52
      Rank: Member

      I have the following function definition:

      function Get-MyService {
      [CmdletBinding()]
      [OutputType([MyService])]
      param
      (
      [Parameter(ParameterSetName = 'main')]
      [switch]$AutoButNotRunning,
      [Parameter(ParameterSetName = 'main')]
      [string]$ComputerName,
      [Parameter(ParameterSetName = 'main',
      ValueFromPipeline = $true,
      ValueFromPipelineByPropertyName = $true)]
      [string]$Name = "*",
      [Parameter(ParameterSetName = 'main')]
      [string]$DisplayName = "*",
      [Parameter(ParameterSetName = 'main')]
      [switch]$IncludeExcludedServices,
      [Parameter(ParameterSetName = 'showFiltered',
      Mandatory = $true)]
      [switch]$ShowFilteredServices
      )

      This successfully isolates the ShowFilteredServices parameter into its own parameter set.  It is also legal to run the cmdlet with no parameters, which also works.

      However, I have been unsuccessful (through the use of parameter sets) in one other objective.  The IncludeExcludedServices switch parameter should require the existence of the AutoButNotRunning parameter.  The AutoButNotRunning parameter does not require the IncludeExcludedServices parameter and the AutoButNotRunning parameter can be used in conjunction with any combination of parameters that are part of the ‘main’ parameter set.

      I don’t want to use dynamic parameters unless that’s the only way to accomplish this.  Currently, I’m using the following code to deal with it, but that’s a cheap workaround.  Any suggestions are greatly appreciated.

      if ($PSBoundParameters.ContainsKey('IncludeExcludedServices') -and (-not $PSBoundParameters.ContainsKey('AutoButNotRunning'))) { <throw error> }

       

    • #229867
      Participant
      Topics: 12
      Replies: 1610
      Points: 2,508
      Helping Hand
      Rank: Community Hero

      It’s required because you are using $PSBoundParameters as a splat? Rather than throw an error, you could just update $PSBounParameters:

      function Get-MyService {
          [CmdletBinding()]
          param (
              [Parameter(ParameterSetName = 'main')]
              [bool]$AutoButNotRunning = $true,
              [Parameter(ParameterSetName = 'main')]
              [string]$ComputerName,
              [Parameter(ParameterSetName = 'main',
                  ValueFromPipeline = $true,
                  ValueFromPipelineByPropertyName = $true)]
              [string]$Name = "*",
              [Parameter(ParameterSetName = 'main')]
              [string]$DisplayName = "*",
              [Parameter(ParameterSetName = 'main')]
              [switch]$IncludeExcludedServices,
              [Parameter(ParameterSetName = 'showFiltered',
              Mandatory = $true)]
              [switch]$ShowFilteredServices
          )
          begin{
              if ($PSBoundParameters.ContainsKey('IncludeExcludedServices') -and (-not $PSBoundParameters.ContainsKey('AutoButNotRunning'))) { 
                  Write-Verbose 'Adding param AutoButNotRunning'
                  $PSBoundParameters.Add('AutoButNotRunning',$true)
              }
          }
          process{      
              $PSBoundParameters
          }
          end{}
      }
      
      Get-MyService -IncludeExcludedServices -Verbose
      

      Output:

      VERBOSE: Adding param AutoButNotRunning
      
      Key                     Value
      ---                     -----
      IncludeExcludedServices True 
      Verbose                 True 
      AutoButNotRunning       True
      

      It depends on how exactly you are referencing the Param in the code within the function. If you are referencing $AutoButNotRunning, then using bool can have a default var.

      function Get-MyService {
          [CmdletBinding()]
          param (
              [Parameter(ParameterSetName = 'main')]
              [bool]$AutoButNotRunning = $true,
              [Parameter(ParameterSetName = 'main')]
              [string]$ComputerName,
              [Parameter(ParameterSetName = 'main',
                  ValueFromPipeline = $true,
                  ValueFromPipelineByPropertyName = $true)]
              [string]$Name = "*",
              [Parameter(ParameterSetName = 'main')]
              [string]$DisplayName = "*",
              [Parameter(ParameterSetName = 'main')]
              [switch]$IncludeExcludedServices,
              [Parameter(ParameterSetName = 'showFiltered',
              Mandatory = $true)]
              [switch]$ShowFilteredServices
          )
          begin{
              Write-Verbose ('AutoButNotRunning: {0}' -f $AutoButNotRunning)
              if ($PSBoundParameters.ContainsKey('IncludeExcludedServices') -and (-not $PSBoundParameters.ContainsKey('AutoButNotRunning'))) { 
                  Write-Verbose 'Adding param AutoButNotRunning'
                  $PSBoundParameters.Add('AutoButNotRunning',$true)
              }
          }
          process{      
              $PSBoundParameters
              
          }
          end{}
      }
      
      Get-MyService -IncludeExcludedServices -Verbose
      

      Output:

      VERBOSE: AutoButNotRunning: True
      
      Key                     Value
      ---                     -----
      IncludeExcludedServices True 
      Verbose 
      

      You have to be careful using $PSBoundParameters directly, as you can see other things like Debug or Verbose can be added to the keys, but those are passed to internal commands as well.

      • This reply was modified 6 days, 7 hours ago by Rob Simmers.
    • #229876
      Participant
      Topics: 7
      Replies: 9
      Points: 52
      Rank: Member

      Thanks for the response.  The AutoButNotRunning param is required when the IncludeExcludedServices param is specified because it’s only relevant in that context.  The AutoButNotRunning param implements the filter that the IncludeExcludedServices param is un-doing.  I wanted to implement it in a way that was self-documenting and so that the Syntax information was as accurate as possible.  In other words, I wanted good code and I wanted to learn how to do it properly.

    • #229882
      Participant
      Topics: 12
      Replies: 1610
      Points: 2,508
      Helping Hand
      Rank: Community Hero

      A filter is dynamically being created and a switch is undoing something, then I’d look at that logic as well. Can you update the filter logic to append the filter based on the IncludeExcludedServices rather than manipulate the parameters. Personally have had to rethink params and logic many times, but have not had to implement dynamic params.

    • #230065
      Participant
      Topics: 7
      Replies: 9
      Points: 52
      Rank: Member

      Thanks again.  I’ll take another look.

    • #230551
      Participant
      Topics: 1
      Replies: 6
      Points: 31
      Rank: Member

      please let me know which command let to find all system defined parameters.

    • #230554
      Participant
      Topics: 4
      Replies: 2231
      Points: 5,414
      Helping Hand
      Rank: Community MVP

      Please do not hijack other peoples threads. If you have a question you should create a new thread for your self.

    • #230569
      Participant
      Topics: 1
      Replies: 6
      Points: 31
      Rank: Member

      how to find total number of parameters in powershell ?

      how to find the total number switch, positional, optional and mandatory parameters and its names  in each version of power shell?

Viewing 7 reply threads
  • You must be logged in to reply to this topic.