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.”
#1 Best Overall
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.
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.
Rank #3
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.
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
- 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
-WhatIfbehavior 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.Review and static-analysis checklist
Use the right binding
- Add
[CmdletBinding(SupportsShouldProcess)]to functions whose verbs imply persistent changes. - Do not declare
WhatIforConfirmparameters manually. - Choose
ConfirmImpactdeliberately; leave the documentedMediumdefault for ordinary changes and reserveHighfor 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.
Best Value
- Used Book in Good Condition
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.

