Home > database >  How to use ParameterSetName for unique combination in powershell cmdlet
How to use ParameterSetName for unique combination in powershell cmdlet

Time:03-18

I am working on preparing PowerShell cmdlet and have to set unique combinations for the inputs such that at a time only a given combination can be applied otherwise it should throw parameter set cannot be resolved using the specified named parameters.

public abstract class ServerCmdletBase
{
    public const string IdParameterSetName = "Id";
    public const string InputObjectParameterSetName = "InputObject";

    [Parameter(Mandatory = true, ParameterSetName = IdParameterSetName)]
    public int[] Id { get; set; }

    [Parameter(Mandatory = true, ParameterSetName = InputObjectParameterSetName)]
    public string[] InputObject { get; set; }

    ...
    ...
}
public class EditServerCmdlet : ServerCmdletBase
{
    public const string ConnectionStringParameterSetName = "ConnectionString";
    public const string PasswordParameterSetName = "Password";

    [Parameter(Mandatory = true, ParameterSetName = ConnectionStringParameterSetName)]
    [Parameter(ParameterSetName = IdParameterSetName )]
    [Parameter(ParameterSetName = InputObjectParameterSetName )]
    public string ConnectionString { get; set; }

    [Parameter(Mandatory = true, ParameterSetName = PasswordParameterSetName)]
    [Parameter(ParameterSetName = IdParameterSetName )]
    [Parameter(ParameterSetName = InputObjectParameterSetName )]
    public string Username { get; set; }

    [Parameter(Mandatory = true, ParameterSetName = PasswordParameterSetName)]
    [Parameter(ParameterSetName = IdParameterSetName )]
    [Parameter(ParameterSetName = InputObjectParameterSetName )]
    public string Password { get; set; }

    ...
    ...
}

The end goal is -Id and -InputObject should not be used at the same time. For the given input (Id or InputObject), -ConnectionString and -Username, -Password should not be used at the same time. Hence total 4 unique combinations.

I am using ParameterSetName here but can't get it to work. The above code only works for Id and InputObject, it can't handle ConnectionString/Username & Password. Please advise for the right approach. Thanks a lot!

CodePudding user response:

Like you have identified 4 different combinations, you also need 4 different parameter sets. 1 combination corresponds to 1 set of parameters.

Since you're using a base class I don't think there's an easy way to reuse the code. So if the extending class needs to expand the number of possible sets and those sets need to include the parameters from the "base sets", you need to override the properties I believe.

Start by making them virtual:

public abstract class ServerCmdletBase
{
    public const string IdParameterSetName = "Id";
    public const string InputObjectParameterSetName = "InputObject";

    [Parameter(Mandatory = true, ParameterSetName = IdParameterSetName)]
    public virtual int[] Id { get; set; }

    [Parameter(Mandatory = true, ParameterSetName = InputObjectParameterSetName)]
    public virtual string[] InputObject { get; set; }

    ...
    ...
}

Now, create your 4 different set names and annotate the properties with those:

public class EditServerCmdlet : ServerCmdletBase
{
    public const string IdConnStrParameterSetName = IdParameterSetName   "ConnectionString";
    public const string InObjConnStrParameterSetName = InputObjectParameterSetName   "ConnectionString";
    public const string IdPwParameterSetName = IdParameterSetName   "Password";
    public const string InObjPwParameterSetName = InputObjectParameterSetName   "Password";

    [Parameter(Mandatory = true, ParameterSetName = IdConnStrParameterSetName)]
    [Parameter(Mandatory = true, ParameterSetName = IdPwParameterSetName)]
    public override int[] Id { get; set; }

    [Parameter(Mandatory = true, ParameterSetName = InObjConnStrParameterSetName)]
    [Parameter(Mandatory = true, ParameterSetName = InObjPwParameterSetName)]
    public override string[] InputObject { get; set; }

    [Parameter(Mandatory = true, ParameterSetName = IdConnStrParameterSetName)]
    [Parameter(Mandatory = true, ParameterSetName = InObjConnStrParameterSetName)]
    public string ConnectionString { get; set; }

    [Parameter(Mandatory = true, ParameterSetName = IdPwParameterSetName)]
    [Parameter(Mandatory = true, ParameterSetName = InObjPwParameterSetName)]
    public string Username { get; set; }

    [Parameter(Mandatory = true, ParameterSetName = IdPwParameterSetName)]
    [Parameter(Mandatory = true, ParameterSetName = InObjPwParameterSetName)]
    public string Password { get; set; }

    ...
    ...
}

Note: this means IdParameterSetName and InputObjectParameterSetName are essentially unused. So, unless you have other classes that derive from ServerCmdletBase that don't need to add other sets, you can probably remove those two "base sets".

  • Related