Parameter Set question

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> }

 

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.

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.

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.

Thanks again. I’ll take another look.

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

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

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?