Advanced Functions
Prerequisites: Functions
Adding [CmdletBinding()] turns a function into an advanced function
— it gains all the behavior of a compiled cmdlet: common parameters like
-Verbose, -ErrorAction, and -WhatIf support.
function Get-DiskUsage {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]$Name,
[ValidateRange('Positive')]
[long]$SizeBytes,
[long]$UsedBytes
)
Write-Verbose "Calculating usage for $Name"
[pscustomobject]@{
Name = $Name
SizeGB = [math]::Round($SizeBytes / 1GB, 1)
PercentUsed = [math]::Round($UsedBytes / $SizeBytes * 100)
}
}
Get-DiskUsage -Name C -SizeBytes 512GB -UsedBytes 384GB -Verbose
VERBOSE: Calculating usage for C
Name SizeGB PercentUsed
---- ------ -----------
C 512.000 75.000
Note that it outputs an object, not a formatted string — callers can sort, filter, or export it.
Common parameters for free
Every advanced function accepts -Verbose, -Debug, -ErrorAction,
-WarningAction, -ErrorVariable, -OutVariable, and more
(Get-Help about_CommonParameters). You don't write any code for them.
The Parameter attribute
function Send-Report {
[CmdletBinding()]
param(
[Parameter(Mandatory, Position = 0, HelpMessage = 'Recipient email')]
[Alias('To')]
[string[]]$Recipient,
[string]$Subject = 'Weekly report'
)
foreach ($r in $Recipient) { "Sending '$Subject' to $r" }
}
Send-Report ada@example.com
Send-Report -To ada@example.com, linus@example.com -Subject 'Q2 numbers'
Sending 'Weekly report' to ada@example.com
Sending 'Q2 numbers' to ada@example.com
Sending 'Q2 numbers' to linus@example.com
Mandatory— required.Position = 0— may be passed without its name.[Alias('To')]— an alternative parameter name.[string[]]— accepts one or more values.
Structure of a good advanced function
- Comment-based help (
.SYNOPSIS,.EXAMPLE). [CmdletBinding()]and aparam()block with types and validation.Write-Verbosefor progress,Write-Errororthrowfor problems.- Output objects — one per item — never formatted text.