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

If an advanced PowerShell function can change files, services, configuration, accounts, or other persistent state, add [CmdletBinding(SupportsShouldProcess)] and put every mutation behind $PSCmdlet.ShouldProcess(). PowerShell then supplies working -WhatIf and -Confirm parameters without you declaring them yourself.

The safe implementation pattern

SupportsShouldProcess is the opt-in switch on the cmdlet-binding attribute. It adds the common -WhatIf and -Confirm parameters to an advanced function; it does not create a $WhatIf variable for you to inspect. The supported design is to call ShouldProcess immediately before the operation that changes state.

function Set-ExampleThing {
    [CmdletBinding(SupportsShouldProcess)]
    param(
        [Parameter(Mandatory)]
        [string] $Name
    )

    # Resolve and validate before checking whether to mutate.
    $target = "ExampleThing '$Name'"

    if ($PSCmdlet.ShouldProcess($target, 'Update')) {
        # Perform the persistent change here.
    }
}

Resolve targets and validate inputs before the guard. That work can still run during a -WhatIf invocation, allowing bad names or inaccessible resources to produce useful errors while the persistent operation is withheld. Keep the guard close to the actual mutation and guard every separate branch that can change state.

Microsoft Learn summarizes the ordering this way: “In the cmdlet code, call the System.Management.Automation.Cmdlet.ShouldProcess method before the operation that changes the system is performed.”

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

WhatShouldProcess actually does

The method returns a Boolean. With ordinary execution it permits the operation when confirmation policy allows it. With -WhatIf, PowerShell displays the proposed action and returns $false, so the code inside the if statement is skipped.

For example, a correctly guarded remove function performs target resolution and validation, then reports what it would remove under -WhatIf without deleting anything. The same method also contributes useful verbose-style action text, so a meaningful target and operation are worth choosing.

Choosing the message overload

Call Result When to use it
ShouldProcess($target) The function name supplies the operation. Use when the generated message is already unambiguous.
ShouldProcess($target, $operation) You name both the target and action. Preferred when “Update,” “Remove,” or another explicit verb makes the preview clearer.
Three-argument overload Lets you customize the confirmation message. Use when the standard target/operation wording does not explain the consequence adequately.

How -WhatIf and -Confirm differ

-WhatIf: preview without mutation

-WhatIf asks the function to describe the action it would take. It is a preview, not evidence that every downstream operation is protected. Direct .NET calls, external applications, and improperly composed script modules can sit outside PowerShell’s automatic confirmation path; the call that mutates state must still be inside your own ShouldProcess branch.

-Confirm: ask before proceeding

-Confirm prompts when the function’s ConfirmImpact meets the caller’s $ConfirmPreference. The documented default impact is Medium. Set a higher impact only for genuinely disruptive work; Microsoft gives reformatting a hard-disk volume as an example of High. The prompt offers choices such as Yes, Yes to All, No, and No to All.

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.

You can set impact on the binding when appropriate:

[CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')]

Do not manually add WhatIf or Confirm switches. PSScriptAnalyzer’s UseSupportsShouldProcess rule warns against that pattern and recommends the attribute-based implementation.

ShouldProcess versus ShouldContinue

Most state-changing functions need only ShouldProcess. ShouldContinue is an optional second, interactive question when the operation needs a more finely scoped “are you sure?” decision. It does not replace the standard guard.

Aspect ShouldProcess ShouldContinue
Primary purpose Standard WhatIf preview and confirmation around a state change. Additional interactive confirmation for a narrower decision.
WhatIf Honors -WhatIf and can return false. Not a substitute for the WhatIf-aware outer check.
Host requirement Designed for normal cmdlet confirmation behavior. Can throw when no interactive prompt is available.
Force Does not disable the ShouldProcess check. A supplied -Force switch should bypass this extra prompt.

If you use ShouldContinue, expose a Force switch and preserve the outer safety check:

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.
if ($PSCmdlet.ShouldProcess($target, 'Reset')) {
    if ($Force -or $PSCmdlet.ShouldContinue(
        "Reset all data for $target?", "Additional confirmation")) {
        # Persistent reset belongs here.
    }
}

With -Force, skip only ShouldContinue; continue calling ShouldProcess so -WhatIf remains effective. Avoid calling ShouldContinue in automation that has no interactive host unless your code path guarantees it will not be reached.

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

Nested modules and preference propagation

Do not assume that $WhatIfPreference or $ConfirmPreference crosses every script-module boundary. Built-in cmdlets, same-scope functions, and some module call patterns commonly behave as expected, but a script module called from a function in another script module may not inherit those preferences reliably.

  • Keep the mutation guard in the function that owns the mutation whenever possible.
  • When wrapping another module command, explicitly forward relevant -WhatIf behavior where the called command supports it.
  • Test the composed modules in the PowerShell version and host where they will run; if propagation is uncertain, assume it will not protect the downstream call automatically.

This boundary matters especially for wrappers: your outer function can print a preview while an inner command, direct .NET operation, or external process still performs a change unless that inner action is independently guarded.

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

Review and static-analysis checklist

Use the right binding

  • Add [CmdletBinding(SupportsShouldProcess)] to functions whose verbs imply persistent changes.
  • Do not declare WhatIf or Confirm parameters manually.
  • Choose ConfirmImpact deliberately; leave the documented Medium default for ordinary changes and reserve High for highly disruptive actions.

Guard every mutation

  • Call $PSCmdlet.ShouldProcess($target, $operation) immediately before each persistent write, delete, start, stop, reset, or update.
  • Place the actual mutation inside the true branch.
  • Use target and operation text that makes a WhatIf message understandable.
  • Remember that direct .NET and external-process changes need the same explicit guard.

Run PSScriptAnalyzer

The always-enabled warning rule UseShouldProcessForStateChangingFunctions identifies state-changing functions using verbs such as New, Set, Remove, Start, Stop, Restart, Reset, and Update when ShouldProcess support is missing. The always-enabled warning rule UseSupportsShouldProcess flags hand-written WhatIf and Confirm parameters and points to the cmdlet-binding attribute instead.

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

Finally, inspect branches manually: static analysis cannot prove that every indirect mutation, nested module call, or external operation is protected. Run a WhatIf scenario, an interactive confirmation scenario, and the non-interactive path used by your automation.

Version and documentation context

This guidance follows the Microsoft Learn documentation views for PowerShell 7.5 and 7.6 and the current PSScriptAnalyzer rule pages cited for this topic. Prompt behavior, module composition, and external operations should be validated in the exact host and PowerShell version targeted by your production module.

Quick Recap

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.