Skip to content
AgileLogics
6 min read

Parameter Validation and Parameter Sets

Prerequisites: Advanced functions

Validation attributes

Validation runs before your code — bad input never reaches it:

Attribute Checks
[ValidateNotNullOrEmpty()] not $null or ''
[ValidateSet('a','b')] one of the listed values (and tab-completes them)
[ValidateRange(1, 100)] a number in range
[ValidateLength(3, 20)] string length
[ValidatePattern('^\d{4}$')] matches a regex
[ValidateScript({ Test-Path $_ })] any custom test
[ValidateCount(1, 5)] number of items in an array
function New-Account {
  [CmdletBinding()]
  param(
    [ValidatePattern('^[a-z][a-z0-9]{2,15}$')]
    [string]$UserName,

    [ValidateScript({ $_ -match '@' }, ErrorMessage = '"{0}" is not an email address.')]
    [string]$Email
  )
  "Created $UserName <$Email>"
}

New-Account -UserName ada99 -Email ada@example.com
try { New-Account -UserName ada -Email 'not-an-email' }
catch { $_.Exception.Message }
try { New-Account -UserName 'Ada Lovelace' -Email ada@example.com }
catch { $_.Exception.Message }
Created ada99 <ada@example.com>
Cannot validate argument on parameter 'Email'. "not-an-email" is not an email address.
Cannot validate argument on parameter 'UserName'. The argument "Ada Lovelace" does not match the "^[a-z][a-z0-9]{2,15}$" pattern. Supply an argument that matches "^[a-z][a-z0-9]{2,15}$" and try the command again.

ErrorMessage (PowerShell 7) replaces the default text with your own; {0} is the rejected value.

Parameter sets

Parameter sets let one command accept different combinations of parameters — like Get-Process -Name versus Get-Process -Id:

function Get-Customer {
  [CmdletBinding(DefaultParameterSetName = 'ByName')]
  param(
    [Parameter(Mandatory, ParameterSetName = 'ByName')]
    [string]$Name,

    [Parameter(Mandatory, ParameterSetName = 'ById')]
    [int]$Id
  )
  switch ($PSCmdlet.ParameterSetName) {
    'ByName' { "Looking up customer named $Name" }
    'ById'   { "Looking up customer #$Id" }
  }
}

Get-Customer -Name Ada
Get-Customer -Id 42
try { Get-Customer -Name Ada -Id 42 } catch { $_.Exception.Message }
Looking up customer named Ada
Looking up customer #42
Parameter set cannot be resolved using the specified named parameters. One or more parameters issued cannot be used together or an insufficient number of parameters were provided.

$PSCmdlet.ParameterSetName tells you which set was used. Get-Help and Get-Command -Syntax show one syntax line per set.

Switch parameters

function Remove-TempFile {
  [CmdletBinding()]
  param([switch]$Force)
  if ($Force) { 'Removing without asking' } else { 'Asking first' }
}
Remove-TempFile
Remove-TempFile -Force
Asking first
Removing without asking

Never give a [switch] a default of $true — a switch should mean "off unless given".