In a previous blog I wrote about PowerShell’s common parameters, today I dive into another aspect of parameters in functions, namely Parameter Sets. Parameter sets allow you to define different sets of parameters for a single function, this helps creating clearer and more intuitive functions.

What Are PowerShell Parameter Sets?

Parameter sets allow you to define different parameter groupings for a function or cmdlet. These groupings, or “sets,” mean that certain parameters can only be used together, while others are mutually exclusive. Parameter sets give you the flexibility to adapt your scripts to different scenarios without needing multiple functions.

For example, let’s say you have a script that can retrieve data from either a file or a database. You can use parameter sets to ensure that only the necessary parameters are available depending on the source. If the user specifies -FilePath, the script will know not to expect database-related parameters, and vice versa.

Benefits of Using Parameter Sets

  • Clearer User Experience: By grouping parameters, you provide users with a clearer path for which options can be used together.
  • Input Validation: PowerShell can automatically validate that only the correct combination of parameters is used, reducing errors.
  • Simplified Code: Instead of writing multiple functions, you can manage variations with a single function and use branching logic inside your function.

Creating Parameter Sets

To create parameter sets, you must specify the ParameterSetName attribute on each parameter that belongs to a specific set. PowerShell will then recognize and validate these groupings. Let’s break down the syntax with an example.

Function Get-Data {

    [CmdletBinding()]

    param (

        [Parameter(Mandatory=$true, ParameterSetName="GetFile")]

        [string]$FilePath,

        [Parameter(Mandatory=$true, ParameterSetName="GetDatabase")]

        [string]$DatabaseName,

        [Parameter(Mandatory=$false, ParameterSetName="GetDatabase")]

        [string]$TableName

    )

    switch ($PSCmdlet.ParameterSetName) {

        "GetFile" {

            # Logic for getting data from a file

            Write-Verbose "Getting data from file: $FilePath"

        }

        "GetDatabase" {

            # Logic for getting data from a database

            Write-Verbose "Getting data from database: $DatabaseName, Table: $TableName"

        }

    }

}

In the above example we have defined a parameter set named GetFile and a set named GetDatabase.

When using -FilePath as an input for the function the result is that you cannot use either of the database related parameters, which prevents the user from providing the wrong kind of input to the function.

Example usage

# Using the FromFile parameter set

Get-Data -FilePath "C:\data\file.txt"

# Using the FromDatabase parameter set

Get-Data -DatabaseName "MyDatabase" -TableName "Customers"

As you can see PowerShell will automatically enforce that you can’t use both -FilePath and -Database together because they are part of different sets.

Advanced Usage of Parameter Sets

PowerShell allows for some more advanced use cases for parameter sets, such as:

Optional Parameters in a Parameter Set

Parameters within a set don’t have to be mandatory. In the FromDatabase set above, -TableName is optional, allowing flexibility depending on the needs of the user.

Shared Parameters Across Sets

You can also create parameters that exist across multiple parameter sets. For example:

param (

    [Parameter(Mandatory=$true, ParameterSetName="FromFile")]

    [Parameter(Mandatory=$true, ParameterSetName="FromDatabase")]

    [string]$OutputPath

)

In the parameterblock above -OutputPath can be used with every defined parameter set. If there is no ParameterSet defined for a parameter it false into the invisible __AllParameters set, which is defined with PowerShell itself. As the name suggests the parameter is automatically tied to all defined sets, making it possible to use this parameter in all scenario’s.

A more complex example

Let’s look at how this works with more complex functions:

Function Start-DataProcessing {

    [CmdletBinding()]

    param (

        [Parameter(Mandatory=$true, ParameterSetName="QuickProcess")]

        [string]$SourcePath,

        [Parameter(Mandatory=$true, ParameterSetName="DeepProcess")]

        [string]$SourcePath,

        [Parameter(Mandatory=$false, ParameterSetName="DeepProcess")]

        [int]$ProcessingDepth

    )

    if ($PSCmdlet.ParameterSetName -eq "QuickProcess") {

        Write-Output "Performing quick processing on $SourcePath"

    }

    elseif ($PSCmdlet.ParameterSetName -eq "DeepProcess") {

        Write-Output "Performing deep processing on $SourcePath with depth $ProcessingDepth"

    }

}

In this example we have:

The QuickProcess parameter set, which only requires a -SourcePath.

The DeepProcess parameter set, which requires -SourcePath but can optionally take a -ProcessingDepth

Conclusion

PowerShell parameter sets are an essential tool for creating flexible and user-friendly scripts. By defining parameter sets, you guide your users towards the correct usage patterns while reducing errors and simplifying your codebase. Incorporating parameter sets will make your scripts more professional, manageable, and powerful.

Leave a Reply

Your email address will not be published. Required fields are marked *