-WhatIf On By Default in PowerShell Cmdlets

I recently came across this blog post on setting -WhatIf on by default in PowerShell. While it works just fine for many use cases, it only seems to apply at the level of an admin's PowerShell session (i.e. by setting the global $WhatIfPreference. I wanted to take it a step further by making this the default action for a specific cmdlet (since I don't necessarily want the admins running this code to have to setup something in their shell before it becomes non-impacting by default).

After a bunch of messing around with my cmdlet, I think I finally got it figured out. I was able to get my desired functionality by adding the following code to the begin block of my cmdlet:

        if (-not ($PSBoundParameters.ContainsKey('WhatIf'))) {
            $WhatIfPreference = $true
        }

This code checks whether the -WhatIf parameter was included, and sets the $WhatIfPreference variable to true if it was not. This essentially turns -WhatIf on by default. Here's an example:

# WhatIfTest.psm1

function Invoke-MyFunction {
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'high')]
    param()

    begin {
        if (-not ($PSBoundParameters.ContainsKey('WhatIf'))) {
            $WhatIfPreference = $true
        }
    }

    process {
        if ($PSCmdlet.ShouldProcess("Should I do a thing?????")) {
            Write-Host "I did a thing!"
        }

        MyHelperFunction
    }
}

function MyHelperFunction {
    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'high')]
    param ()

    process {
        if ($PSCmdlet.ShouldProcess("Should I also do a thing??")) {
            Write-Host "I also did a thing!"
        }
    }
}

Export-ModuleMember -Function Invoke-MyFunction

Running this code will then turn on -WhatIf by default for both the top-level function and anything else called by the function. Then when we need to actually do things, we just call the function with the parameter -WhatIf:$false:

PS C:\> Import-Module -Force .\WhatIfTest.psm1

PS C:\> Invoke-MyFunction
What if: Performing the operation "Invoke-MyFunction" on target "Should I do a thing?????".
What if: Performing the operation "MyHelperFunction" on target "Should I also do a thing??".

PS C:\> Invoke-MyFunction -WhatIf
What if: Performing the operation "Invoke-MyFunction" on target "Should I do a thing?????".
What if: Performing the operation "MyHelperFunction" on target "Should I also do a thing??".

PS C:\> Invoke-MyFunction -WhatIf:$false

Confirm
Are you sure you want to perform this action?
Performing the operation "Invoke-MyFunction" on target "Should I do a thing?????".
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"):
I did a thing!

Confirm
Are you sure you want to perform this action?
Performing the operation "MyHelperFunction" on target "Should I also do a thing??".
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"):
I also did a thing!

This also works in the case of using the -Confirm parameter:

PS C:\> Invoke-MyFunction -Confirm
What if: Performing the operation "Invoke-MyFunction" on target "Should I do a thing?????".
What if: Performing the operation "MyHelperFunction" on target "Should I also do a thing??".

PS C:\> Invoke-MyFunction -Confirm:$false
What if: Performing the operation "Invoke-MyFunction" on target "Should I do a thing?????".
What if: Performing the operation "MyHelperFunction" on target "Should I also do a thing??".

PS C:\> Invoke-MyFunction -Confirm -WhatIf:$false

Confirm
Are you sure you want to perform this action?
Performing the operation "Invoke-MyFunction" on target "Should I do a thing?????".
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"):
I did a thing!

Confirm
Are you sure you want to perform this action?
Performing the operation "MyHelperFunction" on target "Should I also do a thing??".
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "Y"):
I also did a thing!

PS C:\> Invoke-MyFunction -Confirm:$false -WhatIf:$false
I did a thing!
I also did a thing!

Note, that if we want the function to call the code protected by $PSCmdlet.ShouldProcess without any confirmation window (e.g. in the case of other automated tools calling our code), we have to call it with -Confirm:$false -WhatIf:$false

Show Comments