admin管理员组

文章数量:1287880

I have the following

[CmdletBinding(DefaultParametersetName='Help')] 
Param (
    [Parameter(ParameterSetName='Help',Mandatory=$false)]
    [switch]$help,

    [Parameter(ParameterSetName='ReportSilent',Mandatory=$true)]
    [Parameter(ParameterSetName='UpdateSilent',Mandatory=$true)]
    [switch]$silentLogin,

    [Parameter(ParameterSetName='ReportSilent',Mandatory=$true)]
    [Parameter(ParameterSetName='UpdateSilent',Mandatory=$true)]
    [string]$apikey,

    [Parameter(ParameterSetName='Report',Mandatory=$true)]
    [Parameter(ParameterSetName='ReportSilent',Mandatory=$true)]
    [switch]$report,

    [Parameter(ParameterSetName='Report',Mandatory=$true)]
    [Parameter(ParameterSetName='ReportSilent',Mandatory=$true)]
    [string]$scanID,

    [Parameter(ParameterSetName='Report',Mandatory=$false)]
    [Parameter(ParameterSetName='ReportSilent',Mandatory=$false)]
    [string]$filePath = "$PSScriptRoot\Results.csv",

    [Parameter(ParameterSetName='Update',Mandatory=$true)]
    [Parameter(ParameterSetName='UpdateSilent',Mandatory=$true)]
    [switch]$update,

    [Parameter(ParameterSetName='Update',Mandatory=$true)]
    [Parameter(ParameterSetName='UpdateSilent',Mandatory=$true)]
    [string]$input_file
)

If I run the script with just the -Report switch I get an error

Parameter set cannot be resolved using the specified named parameters

I understand that the script cannot determine if it should be belong to parameter set Report or ReportSilent but cannot figure out how to resolve this.

My code works when the required parameters are used but I would like the user to be prompted when a mandatory parameter is missing e.g the following would prompt for apiKey

./script -report

Edit:

As noted by @denisrennes the syntaxes I am looking for are

Update:       -update -input_file <string>
UpdateSilent: -update -input_file <string> -silentLogin -apikey <string> 
Report:       -report -scanID <string> [-filePath <string>]
ReportSilent: -report -scanID <string> [-filePath <string>] -silentLogin -apikey <string>

but I was not clear on the goal.

I am looking for a solution where essentially you have multiple default parameter sets based on the switches used. So if you use only -Report it will default to the set Report and if you use only -Update it will default to the set Update while still defaulting to the set help when no switches are used.

I know you can only declare a single default parameter set but am looking for a way to achieve the same result

I have the following

[CmdletBinding(DefaultParametersetName='Help')] 
Param (
    [Parameter(ParameterSetName='Help',Mandatory=$false)]
    [switch]$help,

    [Parameter(ParameterSetName='ReportSilent',Mandatory=$true)]
    [Parameter(ParameterSetName='UpdateSilent',Mandatory=$true)]
    [switch]$silentLogin,

    [Parameter(ParameterSetName='ReportSilent',Mandatory=$true)]
    [Parameter(ParameterSetName='UpdateSilent',Mandatory=$true)]
    [string]$apikey,

    [Parameter(ParameterSetName='Report',Mandatory=$true)]
    [Parameter(ParameterSetName='ReportSilent',Mandatory=$true)]
    [switch]$report,

    [Parameter(ParameterSetName='Report',Mandatory=$true)]
    [Parameter(ParameterSetName='ReportSilent',Mandatory=$true)]
    [string]$scanID,

    [Parameter(ParameterSetName='Report',Mandatory=$false)]
    [Parameter(ParameterSetName='ReportSilent',Mandatory=$false)]
    [string]$filePath = "$PSScriptRoot\Results.csv",

    [Parameter(ParameterSetName='Update',Mandatory=$true)]
    [Parameter(ParameterSetName='UpdateSilent',Mandatory=$true)]
    [switch]$update,

    [Parameter(ParameterSetName='Update',Mandatory=$true)]
    [Parameter(ParameterSetName='UpdateSilent',Mandatory=$true)]
    [string]$input_file
)

If I run the script with just the -Report switch I get an error

Parameter set cannot be resolved using the specified named parameters

I understand that the script cannot determine if it should be belong to parameter set Report or ReportSilent but cannot figure out how to resolve this.

My code works when the required parameters are used but I would like the user to be prompted when a mandatory parameter is missing e.g the following would prompt for apiKey

./script -report

Edit:

As noted by @denisrennes the syntaxes I am looking for are

Update:       -update -input_file <string>
UpdateSilent: -update -input_file <string> -silentLogin -apikey <string> 
Report:       -report -scanID <string> [-filePath <string>]
ReportSilent: -report -scanID <string> [-filePath <string>] -silentLogin -apikey <string>

but I was not clear on the goal.

I am looking for a solution where essentially you have multiple default parameter sets based on the switches used. So if you use only -Report it will default to the set Report and if you use only -Update it will default to the set Update while still defaulting to the set help when no switches are used.

I know you can only declare a single default parameter set but am looking for a way to achieve the same result

Share Improve this question edited Feb 22 at 23:33 Michael74 asked Feb 22 at 18:56 Michael74Michael74 331 silver badge7 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 1

Here are probably the syntaxes of the parameter sets you wanted:

Update:       -update -input_file <string>
UpdateSilent: -update -input_file <string> -silentLogin -apikey <string> 
Report:       -report -scanID <string> [-filePath <string>]
ReportSilent: -report -scanID <string> [-filePath <string>] -silentLogin -apikey <string>

-Report is in Report or ReportSilent parameter set. In both cases, some mandatory arguments are missing and Powershell has to make the user enter them.

For the Report parameter set, -scanID is missing.

For the ReportSilent parameter set, -scanID and -apikey and -silentLogin are missing.

The problem is that Powershell cannot know which mandatory arguments are missing, as this depends on the parameter set.

The absence of the -SilentLogin switch does not mean here that it is the Report parameter set, as it may simply be missing here in the same way that -scanID is missing too.

If this behavior bothers you, we can do things differently, depending on your needs:

Update:       -update -input_file <string>
UpdateSilent: -updateSilent -input_file <string> -apikey <string> 
Report:       -report -scanID <string> [-filePath <string>]
ReportSilent: -reportSilent -scanID <string> [-filePath <string>] -apikey <string>

or (but you will not be prompted for -silentLogin_apikey ...)

Update: -update -input_file <string>  [-silentLogin_apikey <string>]
Report: -report -scanID <string>  [-filePath <string>] [-silentLogin_apikey <string>] 

I ended up finding a solution that works in the manner I wanted. I used Dynamic Parameters to set the apiKey as mandatory when the silent logon switch is used. It did take me a while to figure out that functions need to be inside the Begin statement but got it all working in the end

It does make the script more complicated and am not sure if it is a better solution than the one provided by @denisrennes so have selected that as the answer.

[CmdletBinding(DefaultParametersetName='Help')] 
Param (

    [Parameter(ParameterSetName='Help',Mandatory=$false)]
    [switch]$help,

    [Parameter(ParameterSetName='Report',Mandatory=$false)]
    [Parameter(ParameterSetName='Update',Mandatory=$false)]
    [switch]$silentLogin,

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

    [Parameter(ParameterSetName='Report',Mandatory=$true,HelpMessage="The Scan ID to returns results for.")]
    [string]$scanID,

    [Parameter(ParameterSetName='Report',Mandatory=$false)]
    [string]$filePath = "$PSScriptRoot\Results.csv",

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

    [Parameter(ParameterSetName='Update',Mandatory=$true,HelpMessage="The input file to process.")]
    [string]$input_file
)

DynamicParam {
    if ($silentLogin) {
        # Define parameter attributes
        $paramAttributes = New-Object -Type System.Management.Automation.ParameterAttribute
        $paramAttributes.Mandatory = $true
        $paramAttributes.HelpMessage = "The API Key used to login"

        # Create collection of the attributes
        $paramAttributesCollect = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute]
        $paramAttributesCollect.Add($paramAttributes)

        # Create parameter with name, type, and attributes
        $dynParam = New-Object -Type System.Management.Automation.RuntimeDefinedParameter("apiKey", [string], $paramAttributesCollect)

        # Add parameter to parameter dictionary and return the object
        $paramDictionary = New-Object -Type System.Management.Automation.RuntimeDefinedParameterDictionary
        $paramDictionary.Add("apiKey", $dynParam)
        return $paramDictionary
    }
}

Begin {
    $apiKey = $PSBoundParameters['apiKey']

    Function test {        
        if ($silentLogin)   { Write-Output "API Key: $apikey" }
        if ($report) { Write-Output "Scan ID: $scanID" }
        if ($update) { Write-Output "Input File: $input_file" }                 
    }
}
Process { 
    test
}

本文标签: powershellAmbiguousParameterSet because of overlapping parameter setsStack Overflow