PoshBytes: CmdletBinding The Secret Sauce for Advanced Functions
In this PoshBytes episode, we turn a humble PowerShell function into an advanced function using CmdletBinding. You will see common parameters come alive, WhatIf and Confirm safety nets, and a pipeline-friendly pattern you can reuse everywhere.
This post is a companion for the video embedded below. Scroll down to see the code from the video.
From function to advanced function in 30 seconds
Basic function: works, but has no Common Parameters like -Verbose, -ErrorAction, etc.
function Get-Greeting {
param(
[string]$Name = 'Earthling'
)
Write-Verbose "Preparing greeting for $Name"
"Hello, $Name"
}
Get-Greeting -Name 'Leslie'
CmdletBinding upgrades your function to an advanced function
function Get-Greeting {
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]$Name
)
Write-Verbose "Preparing greeting for $Name"
"Hello, $Name"
}
Get-Greeting -Name 'Abigail' -Verbose
1) Common Parameters appear magically
Without CmdletBinding, -ErrorAction is ignored
function Get-Greeting {
[CmdletBinding()]
param(
[string]$Name = 'Earthling'
)
Write-Verbose "Preparing greeting for $Name"
if($Name -eq 'Vogon Poet') {
Write-Error "Vogon Poets are not welcome here!"
}
"Hello, $Name"
}
Get-Greeting -Name 'Vogon Poet' -Verbose -ErrorAction Stop
2) Safety features: SupportsShouldProcess for WhatIf and Confirm
A safe “change stuff” function using WhatIf/Confirm
function Remove-DemoFile {
[CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')]
param(
[Parameter(Mandatory)]
[string]$Path
)
if ($PSCmdlet.ShouldProcess($Path, 'Remove file')) {
Remove-Item -Path $Path -Force
Write-Verbose "Removed $Path"
}
}
Demo setup
$demoPath = Join-Path $env:TEMP 'PoshBytes-Demo.txt'
'hello from PoshBytes' | Set-Content -Path $demoPath
Nothing removed, but you can see what WOULD happen
Remove-DemoFile -Path $demoPath -WhatIf
This will prompt (ConfirmImpact High) unless you add -Confirm:$false
Remove-DemoFile -Path $demoPath -Confirm
Adding -Confirm:$false will bypass the prompt
Remove-DemoFile -Path $demoPath -Confirm:$false
Bonus: Make parameter sets like a tiny command-line bureaucracy
Parameter sets: choose Name OR Path. DefaultParameterSetName will allow function to be called without named parameters
function Get-Thing {
[CmdletBinding(DefaultParameterSetName='ByName')]
param(
[Parameter(Mandatory, ParameterSetName='ByName',Position = 0)]
[string]$Name,
[Parameter(Mandatory, ParameterSetName='ByPath',Position = 0)]
[string]$Path
)
"Using parameter set: $($PSCmdlet.ParameterSetName)"
if ($PSCmdlet.ParameterSetName -eq 'ByName') { "You chose Name: $Name" }
if ($PSCmdlet.ParameterSetName -eq 'ByPath') { "You chose Path: $Path" }
}
Get-Thing -Name 'Widget'
Get-Thing -Path 'C:\Temp\Widget.txt'
Get-Thing 'Widget'
Wrap Up
• CmdletBinding turns a function into an advanced function • Enables Common Parameters like Verbose • Makes you look like an error handling guru • SupportsShouldProcess lights up WhatIf and Confirm • Define your default Parameter sets