PoshBytes: CmdletBinding The Secret Sauce for Advanced Functions

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.

https://youtube.com/shorts/Eyq7d6-UHac

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