PowerShell parameter sets are a great tool to have in your function writing arsenal. With PowerShell parameter sets, you can create a function that has different parameters for multiple scenarios. The user can specify different parameters so the function can take different actions based on the input.

In this post, I will show you how to add parameter sets to your PowerShell functions. I will also demonstrate how to tell which parameter set is being used in the function. You can then take different actions based on the parameter set.

Defining PowerShell Parameter Sets

You define PowerShell parameter sets in the function’s param() block. The parameter set name lives in the [Parameter()] attribute. You have probably used this attribute to define if a parameter is mandatory or a parameter’s help message.

I was recently working with an API that required the GroupId to add a member to the group. However, I wanted to add the ability to specify the group name as a parameter. Allowing the user to specify a group name is easier than knowing the group Id.

I needed a function to accept either a group name or group ID but not both. Here is the function with three parameters for adding a user to a group: GroupName, GroupId, and UserName.

function Add-GroupMember {
    param(
        [Parameter(Mandatory = $true)]
        [string]
        $GroupName,

        [Parameter(Mandatory = $true)]
        [string]
        $GroupId,

        [Parameter(Mandatory = $true)]
        [string]
        $UserName
    )
}

Right now, the Mandatory attribute designates the user would have to use both GroupId and GroupName. I need to configure the parameters so only one of these can be used at a time.

In the [Parameter()] attribute, you use the ParameterSetName keyword to define the parameter set. If a parameter is in multiple parameter sets, add additional [Parameter()] attributes to the parameter, like the UserName parameter.

function Add-GroupMember {
    param(
        [Parameter(Mandatory = $true,
            ParameterSetName = 'Name')]
        [string]
        $GroupName,

        [Parameter(Mandatory = $true,
            ParameterSetName = 'Id')]
        [string]
        $GroupId,

        [Parameter(Mandatory = $true,
            ParameterSetName = 'Name')]
        [Parameter(Mandatory = $true,
            ParameterSetName = 'Id')]
        [string]
        $UserName
    )
}

In this case, since the UserName parameter is used in both sets, you don’t need to assign it to any of them. Parameters without an assigned parameter set name will automatically be in all sets. Here is the updated function code leaving UserName without an assigned parameter set.

function Add-GroupMember {
    param(
        [Parameter(Mandatory = $true,
            ParameterSetName = 'Name')]
        [string]
        $GroupName,

        [Parameter(Mandatory = $true,
            ParameterSetName = 'Id')]
        [string]
        $GroupId,

        [Parameter(Mandatory = $true)]
        [string]
        $UserName
    )
}

Define a Function’s Default Parameter Set

If you have multiple parameter sets, you specify a default using the DefaultParameterSetName property in the [CmdletBinding()] attribute. PowerShell uses the default set when it doesn’t have enough information to know which set to use. I defined Id as the default parameter set for this function since the API preferred using the Id.

function Add-GroupMember {
    [CmdletBinding(DefaultParameterSetName = 'Id')]
    param(
        [Parameter(Mandatory = $true,
            ParameterSetName = 'Name')]
        [string]
        $GroupName,

        [Parameter(Mandatory = $true,
            ParameterSetName = 'Id')]
        [string]
        $GroupId,

        [Parameter(Mandatory = $true)]
        [string]
        $UserName
    )
}

If you execute the function using only the -UserName parameter, PowerShell will prompt for the GroupId parameter since it is in the default parameter set. The GroupId parameter is also mandatory for that parameter set.

Add-GroupMember -UserName "{user}"
PowerShell prompting for parameter in the default set

A parameter doesn’t have to be mandatory in every parameter set. You can define a parameter as mandatory in one set but optional in another.

Determining Which Parameter Set is Being Used

You’ve defined parameter sets for the function. How can you determine which parameter set was used on the function’s execution? For this, you use the automatic variable $PSCmdlet. The $PSCmdlet variable contains information about the current running cmdlet or function. It contains the property ParameterSetName that contains the parameter set in effect for the command.

One way you verify the parameter set being used is by using an if statement. Compare the value of $PSCmdlet.ParameterSetName to a parameter set’s name to branch the function’s logic. This example checks if the Name parameter set is being used.

if ($PSCmdlet.ParameterSetName -eq 'Name') {
    # Code to go find Id based on Name
}

Another option is to use a switch case statement. You test the value of $PSCmdlet.ParameterSetName, and each condition will match a parameter set name. Each condition performs the necessary action. Here is an example that will output text showing which condition is being used.

switch ($PSCmdlet.ParameterSetName) {
    'Name' {
        Write-Host 'You used the Name parameter set.'
        break
    }
    'Id' {
        Write-Host 'You used the Id parameter set.'
        break
    }
}
Output of using a switch statement

Closing

Parameter sets are a great tool to have if you are writing a function that needs to have different parameters under different scenarios. Normally, you want to create separate functions to handle multiple scenarios, but in the example above, I gave the user the option of specifying the name or the Id, but not both.

Additional reading:
Microsoft Docs | About parameter sets
Microsoft Docs | DefaultParameterSetName

If you enjoyed this article, check out my other PowerShell posts.

Questions or comments? If so, leave a comment below or find me on Twitter or LinkedIn to discuss further.

Leave a Reply