Behind the PowerShell Pipeline logo

Behind the PowerShell Pipeline

Subscribe
Archives
May 13, 2025

More PowerShell Parameter Attributes

When you write a PowerShell function, you need to pay close attention to the parameters you define. The attributes you use can greatly affect how your function behaves and how users interact with it. You want to design parameters that make your code easy to use and that will set up the user for success. I've written about and demonstrated many parameter techniques in the past. Today, I want to cover a few lesser known parameter attributes. I can't guarantee that all of them will work in Windows PowerShell, but you should be able to use them PowerShell 7.`

AllowEmpty

When you define a parameter and make it mandatory, you force the user to provide a value.

Function Get-RemoteData {
    [cmdletbinding()]
    Param(
        [Parameter(Position = 0, Mandatory)]
        [string]$ComputerName
    )

    Write-Verbose 'Using these parameters'
    $PSBoundParameters | Out-String | Write-Verbose

    Write-Host "Processing $computername" -ForegroundColor green
}

The user can't run the function without providing a value for the ComputerName parameter.

PS C:\> Get-RemoteData

cmdlet Get-RemoteData at command pipeline position 1
Supply values for the following parameters:
ComputerName:
Get-RemoteData: Cannot bind argument to parameter 'ComputerName' because it is an empty string.
PS C:\> Get-RemoteData

cmdlet Get-RemoteData at command pipeline position 1
Supply values for the following parameters:
ComputerName:

If you need to allow it, it is possible to allow empty values. You can do this by using the AllowEmptyString() attribute. It is up to you to decide how to handle the empty value. One option is to set a default value. Normally, you can't set a default value for a mandatory parameter, but you can do it with the AllowEmptyString() attribute.

Function Get-RemoteData {
    [cmdletbinding()]
    Param(
        [Parameter(Position = 0, Mandatory)]
        [AllowEmptyString()]
        [string]$ComputerName
    )

    Write-Verbose 'Using these parameters'
    $PSBoundParameters | Out-String | Write-Verbose
    if (-Not $ComputerName) {
        Write-Host 'No computer names provided. Insert code here' -ForegroundColor yellow
        #maybe provide a default or fallback
        $Computername = $env:COMPUTERNAME
    }

    Write-Host "Processing $computername" -ForegroundColor green
}

Here's what it looks like in action:

PS C:\> Get-RemoteData

cmdlet Get-RemoteData at command pipeline position 1
Supply values for the following parameters:
ComputerName:
No computer names provided. Insert code here
Processing PROSPERO

This also works if the user is getting a value from somewhere else and it is empty.

PS C:\> $n = ""
PS C:\> Get-RemoteData $n
No computer names provided. Insert code here
Processing PROSPERO

This also works for collections such as when the parameter accepts an array of values.

Function Get-RemoteData {
    [cmdletbinding()]
    Param(
        [Parameter(Position = 0, Mandatory)]
        [AllowEmptyCollection()]
        [string[]]$ComputerName
    )

    Write-Verbose 'Using these parameters'
    $PSBoundParameters | Out-String | Write-Verbose
    if ($ComputerName.Count -eq 0) {
        Write-Host 'No computer names provided. Insert code here' -ForegroundColor yellow
        #maybe provide a default or fallback
        $Computername = $env:COMPUTERNAME
    }

    foreach ($cn in $Computername) {
        Write-Host "Processing $cn" -ForegroundColor green
    }
}

I'm using the same behavior as before.

PS C:\> Get-RemoteData Foo,Bar
Processing Foo
Processing Bar
PS C:\> $a = @()
PS C:\> Get-RemoteData $a
No computer names provided. Insert code here
Processing PROSPERO

The command will run with an empty value, so you need to decide how that affects your code.

PSDefaultValue

Some parameter attributes are designed as documentation aids. It is not uncommon to define a default value for a parameter.

Function Get-Thing {
    <#
    .SYNOPSIS
    Get things from a path
    .Parameter Path
    Select a path for things to process
    #>
    [cmdletbinding()]
    Param(
        [Parameter(Position = 0, HelpMessage = 'Select a path to process')]
        [string]$Path = "."
    )

    $path = Convert-Path $Path
    Write-Host "Getting things from $Path"
}
Want to read the full issue?
GitHub Bluesky LinkedIn About Jeff
This email brought to you by Buttondown, the easiest way to start and grow your newsletter.