If you are writing PowerShell functions, and you know a particular function has the potential to cause a lot of harm, there is an easy way of adding an extra safety net. Below are two functions, one without safety net, and one with a safety net:

function NoSafety
{
    param
    (
        [Parameter(Mandatory)]
        $Something
    )
    "HARM DONE with $Something!"
}

function Safety
{
    # step 1: add -WhatIf and -Confirm, and mark as harmful
    [CmdletBinding(SupportsShouldProcess,ConfirmImpact="High")]
    param
    (
        [Parameter(Mandatory)]
        $Something
    )
    
    # step 2: abort function when confirmation was rejected
    if (!$PSCmdlet.ShouldProcess($env:computername, "doing something harmful"))
    {
        Write-Warning "Aborted!"
        return
    }
    
    "HARM DONE with $Something!"
}

When you run “NoSafety”, it starts running right away. When you run “Safety”, the user gets a confirmation prompt, and only when the confirmation is accepted will the function run.

There are two parts to this. First, a [CmdletBinding(…)] statement adds the -WhatIf and -Confirm parameters, and ConfirmImpact=”High” marks the function as potentially dangerous.

Second, the first thing in your function code is a call to $PSCmdlet.ShouldProcess where you define the confirmation message. If the call returns $false, the -not operator (!) in the code flips the result, and the function simply aborts.

The user can still run the function without confirmation, either by turning confirmation explicitly off:

 
PS> Safety -Something test -Confirm:$false
HARM DONE with test! 
 

Or, by setting $ConfirmPreference to “None”, effectively turning off all automatic confirmation dialogs for the current PowerShell session:

 
PS> $ConfirmPreference = "None"

PS> Safety -Something test
HARM DONE with test!
 

Twitter This Tip! ReTweet this Tip!

Anonymous
  • The best way is of course using a switch instead of having 2 functions, on the modules I write, I keep the "safe" way as a default, using the switch will just execute.

    e.g. Remove-LabSystem -ComputerName MyPcName -NoConfirmation

    If the -NoConfirmation switch is present, DELETE!!!