How to make PowerShell Dynamic parameters more dynamic?

48 views Asked by At

Here is my code

function test-function {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory = $false, ParameterSetName = 'parameter set A')][switch]$Default,
        [Parameter(Mandatory = $false, ParameterSetName = 'parameter set B')][switch]$NoFlightRoots,

        # [Parameter(Mandatory = $false, ParameterSetName = 'parameter set A')]
        # [Parameter(Mandatory = $false, ParameterSetName = 'parameter set B')]
        # [switch]$PrepMode,

        # [Parameter(Mandatory = $false, ParameterSetName = 'parameter set A')]
        # [Parameter(Mandatory = $false, ParameterSetName = 'parameter set B')]
        # [switch]$AuditAndEnforce,

        [Parameter(Mandatory = $false, ParameterSetName = 'parameter set A')]
        [Parameter(Mandatory = $false, ParameterSetName = 'parameter set B')]
        [Switch]$SomeMoreParameter,

        [Parameter(Mandatory = $false, ParameterSetName = 'parameter set A')]
        [Parameter(Mandatory = $false, ParameterSetName = 'parameter set B')]
        [Switch]$SomeMoreParameter2
    )

    DynamicParam {
        if (
($PSBoundParameters['Default']) -or ($PSBoundParameters['NoFlightRoots'])
        ) {
           
            # Add the dynamic parameters to the param dictionary
            $paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new()

            if (!$PSBoundParameters['PrepMode']) {

                # Create a dynamic parameter for AuditAndEnforce
                $AuditAndEnforceDynamicParameter = [System.Management.Automation.ParameterAttribute]@{
                    Mandatory        = $false
                    ParameterSetName = '__AllParameterSets'
                    HelpMessage      = 'The mode to audit and enforce the policy.'
                }
            
                $paramDictionary.Add('AuditAndEnforce', [System.Management.Automation.RuntimeDefinedParameter]::new(
                        'AuditAndEnforce',
                        [switch],
                        [System.Management.Automation.ParameterAttribute[]]@($AuditAndEnforceDynamicParameter)
                    ))
            }           

            if (!$PSBoundParameters['AuditAndEnforce']) {

                # Create a dynamic parameter for PrepMode
                $PrepModeDynamicParameter = [System.Management.Automation.ParameterAttribute]@{
                    Mandatory        = $false
                    ParameterSetName = '__AllParameterSets'
                    HelpMessage      = 'The name of the computer to sign the policy for.'
                }

                $paramDictionary.Add('PrepMode', [System.Management.Automation.RuntimeDefinedParameter]::new(
                        'PrepMode',
                        [switch],
                        [System.Management.Automation.ParameterAttribute[]]@($PrepModeDynamicParameter)
                    ))
            }
           
            return $paramDictionary
        }
    }

    begin {}

    process {} 
}
test-function -Default

The goal is to make the -PrepMode and -AuditAndEnforce parameters mutually exclusive without showing any errors. It's all about the PowerShell parameter suggestion on the console.

I tried different ways, and this is the closest I've got so far. The code has a problem, I need a way to force Dynamic Parameter block to be more dynamic, i.e. I need it to re-evaluate the selected parameters more than once.

When I do this

test-function -Default -PrepMode

I don't want -AuditAndEnforce to be suggested next, and vice versa.

I use PowerShell 7.3.

The reason I can select both right now is because the Dynamic parameter block only evaluates the selected parameters once, and since it sees that none of those 2 parameters are already selected, it offers both of them, but the moment I select one of the dynamic parameters, I need that block to run again to renew its logic based on the selected dynamic parameters.

0

There are 0 answers