PowerShell Parameters: Advanced Function Parameters Guide

A function without parameter validation is an accident waiting to happen — wrong value, wrong type, no error until something fails deep in the logic. PowerShell function parameters with validation attributes, parameter sets, and pipeline binding turn a basic function into a self-documenting, self-validating tool that’s as safe to call as a built-in cmdlet. This post covers every advanced parameter feature with practical examples for each.
Mandatory Parameters
Mark a parameter with [Parameter(Mandatory)] to require it at call time. If the caller omits it, PowerShell prompts interactively — or throws a non-interactive error in scripts. Mandatory parameters should have no default value.
function Send-Alert {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]$To,
[Parameter(Mandatory)]
[string]$Message,
[string]$Subject = "Automated Alert" # Optional with default
)
Write-Output "Sending to $To: $Subject — $Message"
}
Send-Alert -To "[email protected]" -Message "Disk full"
# Send-Alert -Message "test" # Prompts for -To
Default Values
Optional parameters have default values assigned in the parameter declaration. Defaults apply when the parameter is not supplied by the caller.
function Get-LogEntries {
[CmdletBinding()]
param(
[string]$LogPath = "C:\Logs\app.log",
[int]$LastN = 100,
[string]$Level = "ERROR",
[datetime]$Since = (Get-Date).AddDays(-1)
)
Write-Output "Reading $LastN entries from $LogPath since $($Since.ToString('yyyy-MM-dd'))"
}
Get-LogEntries # Uses all defaults
Get-LogEntries -LastN 500 -Level "WARN" # Overrides two defaults
ValidateSet for Allowed Values
[ValidateSet()] restricts a parameter to a predefined list of values. PowerShell validates at call time and provides tab completion for the allowed values — no manual validation code needed.
function Deploy-App {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]$AppName,
[Parameter(Mandatory)]
[ValidateSet("Development", "Staging", "Production")]
[string]$Environment
)
Write-Output "Deploying $AppName to $Environment"
}
Deploy-App -AppName "WebAPI" -Environment "Staging"
# Deploy-App -AppName "WebAPI" -Environment "QA" # ERROR: invalid value
Deploying WebAPI to Staging
ValidateRange and ValidatePattern
[ValidateRange(min, max)] enforces numeric bounds. [ValidatePattern("regex")] validates string format against a regex. Both throw a parameter validation error at call time if the value doesn’t meet the constraint.
function Set-RetentionDays {
[CmdletBinding()]
param(
[ValidateRange(1, 365)]
[int]$Days = 30,
[ValidatePattern("^[A-Z]{2,5}$")]
[string]$PolicyCode
)
Write-Output "Retention: $Days days, Policy: $PolicyCode"
}
Set-RetentionDays -Days 90 -PolicyCode "GDPR"
# Set-RetentionDays -Days 400 # ERROR: 400 is outside 1-365
# Set-RetentionDays -Days 30 -PolicyCode "lowercase" # ERROR: fails pattern
Parameter Sets
Parameter sets let you define mutually exclusive groups of parameters — like -ComputerName (for remote) vs -Session (for reuse). Each set must be distinguishable by at least one unique mandatory parameter.
function Connect-Target {
[CmdletBinding(DefaultParameterSetName = "ByName")]
param(
[Parameter(Mandatory, ParameterSetName = "ByName")]
[string]$ComputerName,
[Parameter(ParameterSetName = "ByName")]
[System.Management.Automation.PSCredential]$Credential,
[Parameter(Mandatory, ParameterSetName = "BySession")]
[System.Management.Automation.Runspaces.PSSession]$Session
)
Write-Output "Using parameter set: $($PSCmdlet.ParameterSetName)"
if ($PSCmdlet.ParameterSetName -eq "ByName") {
Write-Output "Connecting to: $ComputerName"
} else {
Write-Output "Using existing session"
}
}
Set DefaultParameterSetName on [CmdletBinding()] to avoid ambiguity errors when no mandatory parameters are provided.
Pipeline Input with ValueFromPipeline
Enable pipeline binding with ValueFromPipeline or ValueFromPipelineByPropertyName. When accepting pipeline input, wrap the body in a process block so each piped item is handled individually.
function Test-HostAvailability {
[CmdletBinding()]
param(
[Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
[string]$ComputerName
)
process {
[PSCustomObject]@{
ComputerName = $ComputerName
Online = (Test-Connection -ComputerName $ComputerName -Count 1 -Quiet)
}
}
}
# Pipeline input — processes each server individually
"server01", "server02", "server03" | Test-HostAvailability
# Also works with direct parameter
Test-HostAvailability -ComputerName "server01"
Common Errors and Fixes
- Parameter sets require DefaultParameterSetName to avoid ambiguity: If you define multiple parameter sets but don’t set
DefaultParameterSetNameon[CmdletBinding()], PowerShell may throw an “Ambiguous parameter set” error when the caller omits all mandatory parameters. Always specify a default set even if you think callers will always supply required parameters. - Pipeline binding requires process{} block: Without a
process {}block, a function withValueFromPipelineonly processes the last piped item — all previous items are silently discarded. Thebegin {}block runs once before any pipeline input;process {}runs once per item;end {}runs once after all items are processed. For pipeline-enabled functions, the body must go inprocess {}.
Related Cmdlets / See Also
Wrapping Up
Advanced parameter validation transforms functions from flexible-but-fragile to robust-and-self-documenting. ValidateSet and ValidateRange are the highest-value attributes to add first — they eliminate an entire class of input validation bugs with one line. As a next step, add [CmdletBinding()] and appropriate validation attributes to the three most-called functions in your current scripts.


