Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

[CmdletBinding()] tells PowerShell to treat a function as an advanced function: a script function with cmdlet-style parameter binding and access to common parameters and the automatic $PSCmdlet variable. It does not compile the function or make changes safe automatically. For meaningful -WhatIf and -Confirm behavior, you must opt in with SupportsShouldProcess and guard each side effect with $PSCmdlet.ShouldProcess().

From a simple function to an advanced function

A simple function can accept parameters and return output:

function Get-Thing {
    param([string]$Name)
    "Thing: $Name"
}

Add [CmdletBinding()] immediately before param(), and the function participates in PowerShell’s advanced-function model:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
function Get-Thing {
    [CmdletBinding()]
    param([string]$Name)

    Write-Verbose "Looking up $Name"
    "Thing: $Name"
}

Now you can call it with cmdlet-style common parameters:

Get-Thing -Name 'Test' -Verbose
Get-Thing -Name 'Test' -ErrorAction Stop

An advanced function is still a PowerShell script function, not a compiled .NET cmdlet. It offers many cmdlet-like features without requiring a compiled implementation. A function can also become advanced by using parameter attributes such as [Parameter()], but [CmdletBinding()] clearly signals that you are designing it as a command. See Microsoft’s advanced functions documentation.

What it adds automatically

An advanced function receives common parameters from PowerShell at runtime; you do not declare them in param(). They include:

Parameters What they are for
-Verbose, -Debug Enable messages your function emits with Write-Verbose and Write-Debug.
-ErrorAction, -ErrorVariable Control non-terminating error behavior and capture error records.
-WarningAction, -WarningVariable Control and capture warning-stream messages.
-InformationAction, -InformationVariable Control and capture information-stream records (PowerShell 5.0+).
-OutVariable, -OutBuffer, -PipelineVariable Capture output, adjust output buffering, or make a pipeline object available in a variable.
-ProgressAction Control progress messages (PowerShell 7.4+).

These parameters do not produce messages by themselves. For example, -Verbose only displays messages that the function writes to the verbose stream:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
function Test-Output {
    [CmdletBinding()]
    param()

    Write-Verbose 'Starting work'
    Write-Warning 'Check the input'
    'Result'
}

Test-Output -Verbose

Use Get-Command Test-Output -Syntax to inspect the command syntax, or Get-Help Test-Output -Full to see its help. Do not declare your own parameters with common-parameter names such as Verbose or ErrorAction.

Rank #2
Sale
PowerShell for Sysadmins: Workflow Automation Made Easy
  • Book - powershell for sysadmins: workflow automation made easy
  • Language: english
  • Binding: paperback

For the complete list and details, consult Microsoft’s common parameters reference.

Cmdlet-style parameter binding

[CmdletBinding()] activates cmdlet-style parameter binding. Parameters can use attributes for mandatory input, validation, parameter sets, and pipeline binding. The function also rejects unknown parameter names and unmatched positional arguments instead of silently absorbing them. PowerShell may accept an unambiguous abbreviation, but full parameter names make scripts easier to read and less fragile.

For example, this call fails because -Pth is not a declared parameter:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
function Get-Report {
    [CmdletBinding()]
    param([string]$Path)

    "Reading $Path"
}

Get-Report -Pth 'report.csv'

Function parameters are positionally bindable by default. To require callers to name parameters, set PositionalBinding = $false:

function Get-Report {
    [CmdletBinding(PositionalBinding = $false)]
    param([string]$Path)

    "Reading $Path"
}

Get-Report -Path 'report.csv'

An explicit [Parameter(Position = 0)] still assigns a position. Use positions deliberately—particularly in a public function—rather than relying on parameter order as an accidental part of the interface. PositionalBinding was introduced in Windows PowerShell 3.0.

Other parameter behavior is not automatic. Use [Parameter(Mandatory)] to require an argument, [Parameter(ValueFromPipeline)] or [Parameter(ValueFromPipelineByPropertyName)] to accept pipeline input, and validation attributes such as [ValidateSet()] to constrain values. The advanced parameter reference explains these attributes and parameter sets.

Pipeline input and the begin, process, and end blocks

Adding [CmdletBinding()] makes the advanced-function execution model available, but pipeline input still needs a parameter declaration and suitable code structure. In a pipeline-oriented function, put per-object work in process:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
function Convert-Name {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline)]
        [string]$Name
    )

    process {
        "Converted: $($Name.ToUpperInvariant())"
    }
}

'Ada', 'Grace' | Convert-Name

The begin block runs once before pipeline processing, process runs for each incoming object, and end runs once after processing. Keeping per-item work in process makes the function’s behavior clear and ensures it handles each pipeline item as intended. Merely declaring a pipeline parameter does not replace choosing the right block.

$PSCmdlet: the function’s command context

With [CmdletBinding()], the automatic $PSCmdlet variable provides access to the current command’s context. Common uses include:

  • $PSCmdlet.ParameterSetName to find the active parameter set.
  • $PSCmdlet.MyInvocation to inspect invocation information.
  • $PSCmdlet.ShouldProcess() to gate an operation that changes state.
  • $PSCmdlet.WriteError() and $PSCmdlet.ThrowTerminatingError() to report errors through cmdlet-style mechanisms.
  • $PSCmdlet.PagingParameters when implementing paging.

One related difference: in a function using CmdletBinding, $args is not available in the same way as it is in a simple function. Declare the parameters you intend to accept.

Make -WhatIf and -Confirm real safeguards

For a function that changes or removes data, [CmdletBinding(SupportsShouldProcess)] adds the -WhatIf and -Confirm parameters. That declaration alone does not protect anything. The function must call $PSCmdlet.ShouldProcess(), and the actual side effect must happen only if the call returns true.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Unsafe: the function advertises the switches but deletes the file regardless:

function Remove-Report {
    [CmdletBinding(SupportsShouldProcess)]
    param([string]$Path)

    Remove-Item -LiteralPath $Path
}

Safe pattern:

function Remove-Report {
    [CmdletBinding(SupportsShouldProcess)]
    param(
        [Parameter(Mandatory)]
        [string]$Path
    )

    process {
        if ($PSCmdlet.ShouldProcess($Path, 'Remove report')) {
            Remove-Item -LiteralPath $Path
        }
    }
}

Remove-Report -Path .old.txt -WhatIf
Remove-Report -Path .old.txt -Confirm

With -WhatIf, PowerShell reports what it would do without running the guarded operation. -Confirm asks before proceeding, subject to confirmation preferences. Never perform part of the change before the ShouldProcess check or leave a side effect outside its if block. See Microsoft’s ShouldProcess guide.

ConfirmImpact controls how a command’s impact is compared with $ConfirmPreference; it does not guarantee that a prompt always appears. The documented default impact is Medium, and this setting matters in conjunction with SupportsShouldProcess. A destructive command might use [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')], but callers can still explicitly choose -Confirm or -Confirm:$false.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Diagnostics and errors

Common parameters control streams; your function must write to the relevant stream. Use Write-Verbose for optional diagnostic details, Write-Debug for debug messages, and Write-Warning for warnings. Ordinary output is not verbose output, and Write-Host is not a substitute for Write-Verbose.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

PowerShell distinguishes terminating and non-terminating errors. -ErrorAction Stop escalates non-terminating errors from the command so a surrounding try/catch can handle them:

try {
    Get-Item -LiteralPath $Path -ErrorAction Stop
}
catch {
    # Handle the error record
}

It does not control every terminating error, nor does it remove the need to decide deliberately how your function reports failures. For advanced functions, use $PSCmdlet.WriteError() when you need cmdlet-style non-terminating error semantics, or $PSCmdlet.ThrowTerminatingError() when you intend to stop with an error record. Microsoft’s error-handling reference covers the distinction.

Optional CmdletBinding settings

The attribute can configure more than the default advanced-function behavior:

  • DefaultParameterSetName selects a parameter set if PowerShell cannot otherwise resolve one. Prefer making each set’s distinguishing parameter mandatory where that makes sense.
  • SupportsPaging adds -First, -Skip, and -IncludeTotalCount. Your function must read $PSCmdlet.PagingParameters and honor those values; adding the switches without implementing paging misleads callers. For large data stores, paging at the data source is generally better than fetching everything and slicing locally.
  • HelpUri associates an online help address with the command, which can support Get-Help -Online. It is metadata, not a replacement for comment-based help documenting parameters, examples, and behavior.
  • PositionalBinding controls default positional binding, as described above.

Boolean options can use shorthand, for example [CmdletBinding(SupportsShouldProcess)], equivalent to SupportsShouldProcess = $true. SupportsPaging was introduced in Windows PowerShell 3.0. Advanced functions do not support transactions; workflow-related Suspend behavior is not supported in PowerShell 6 and later. Consult the CmdletBinding reference for the supported settings.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A practical design checklist

  • Use [CmdletBinding()] when a function is reusable, public, pipeline-oriented, or meant to provide a command-like interface. A short private helper may not need it.
  • Declare mandatory, validated, and pipeline-bound parameters explicitly; the attribute does not supply those behaviors for you.
  • Decide whether callers should use positional arguments. Consider PositionalBinding = $false for a large or potentially ambiguous interface.
  • Use Write-Verbose and the other stream-writing commands if you want the corresponding common parameters to have visible effects.
  • For every state-changing operation, opt in with SupportsShouldProcess and put the side effect inside a ShouldProcess() condition.
  • Put per-object pipeline work in process, and implement paging or parameter sets fully if you expose them.
  • Document a public function with comment-based help; add HelpUri when you maintain useful online documentation.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.