Supporting -WhatIf and -Confirm
Prerequisites: Advanced functions
Any function that changes something should support -WhatIf and
-Confirm, exactly like Remove-Item. It takes two small additions.
function Remove-OldLog {
[CmdletBinding(SupportsShouldProcess)]
param(
[string]$Path = '.',
[int]$Days = 30
)
$cutoff = (Get-Date).AddDays(-$Days)
Get-ChildItem -Path $Path -Filter *.log |
Where-Object LastWriteTime -lt $cutoff |
ForEach-Object {
if ($PSCmdlet.ShouldProcess($_.Name, 'Delete log')) {
Remove-Item -LiteralPath $_.FullName
}
}
}
'old.log', 'older.log', 'today.log' | ForEach-Object { New-Item $_ | Out-Null }
(Get-Item old.log).LastWriteTime = (Get-Date).AddDays(-45)
(Get-Item older.log).LastWriteTime = (Get-Date).AddDays(-90)
Remove-OldLog -WhatIf
(Get-ChildItem -Filter *.log).Count
Remove-OldLog
Get-ChildItem -Filter *.log -Name
What if: Performing the operation "Delete log" on target "old.log".
What if: Performing the operation "Delete log" on target "older.log".
3
today.log
[CmdletBinding(SupportsShouldProcess)]adds the-WhatIfand-Confirmparameters.- Wrap each change in
if ($PSCmdlet.ShouldProcess(target, action)). With-WhatIf, it prints a message and returns$false; with-Confirm, it asks; otherwise, it returns$true.
-WhatIf also flows into cmdlets you call — the Remove-Item inside
would respect it even without the if. The explicit check gives you a
clear message and lets you skip other work, like logging.
ConfirmImpact
For dangerous operations, add ConfirmImpact = 'High': PowerShell then
asks for confirmation by default, unless the caller passes
-Confirm:$false.
# illustrative
function Reset-Database {
[CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')]
param([string]$Name)
if ($PSCmdlet.ShouldProcess($Name, 'Drop and recreate')) {
# ...
}
}
Common mistakes
- Declaring
SupportsShouldProcessbut never callingShouldProcess—-WhatIfthen silently does nothing useful. PSScriptAnalyzer warns about this.