03 / RELIABLE ADMINISTRATION TOOLS · LESSON 10

Preview a configuration change with WhatIf

Make a sandbox file update respect PowerShell’s ShouldProcess contract.

15 min · learn at your pace

Put the mutation behind a decision

Advanced functions can opt into PowerShell's -WhatIf and -Confirm parameters with [CmdletBinding(SupportsShouldProcess)]. Call $PSCmdlet.ShouldProcess(target, action) immediately before the operation that changes state. If it returns false, the mutation must not happen.

if ($PSCmdlet.ShouldProcess($Path, 'Update configuration')) {
    # The actual write belongs here.
}

-WhatIf describes the proposed operation and makes ShouldProcess return false. There is no automatically created $WhatIf variable to inspect. Adding SupportsShouldProcess without guarding the write is not enough to establish a reliable function contract.

Keep the guarantee narrow and testable

This exercise updates only LogRetentionDays in a supplied JSON file. Read the existing settings, preserve unrelated keys, and write the updated object only after ShouldProcess approves. File reading and validation can happen before the guard; they must not change the input.

WhatIf is not a transaction, rollback system, or permission check. Code outside the guard can still have effects, and wrappers should not assume every nested operation honours a preference automatically. We will verify the actual file bytes under WhatIf in a later testing lesson.

The only possible change here is to a file in this browser lab. You are not configuring Windows logging or a live server. Use -WhatIf when trying the function first, then run normally to observe the saved JSON.

Go deeper

Read the official reference.

Try an example.ps1
Get-Content '/home/user/settings.json' -Raw | ConvertFrom-Json
YOUR TURN

Put it into practice.

Define Set-ConfigRetention -Path -Days with SupportsShouldProcess. Accept Days 1–365 and update only LogRetentionDays in the supplied JSON, preserving unrelated keys. With -WhatIf, leave the file byte-for-byte unchanged. Throw on invalid Days. Do not emit settings as a success result; inspecting the file is enough. If you call it in your main script, use -WhatIf.

See an explained solution
One way to solve it.ps1
function Set-ConfigRetention {
    [CmdletBinding(SupportsShouldProcess)]
    param([string]$Path, [ValidateRange(1,365)][int]$Days)
    $settings = Get-Content -LiteralPath $Path -Raw -ErrorAction Stop | ConvertFrom-Json -AsHashtable -ErrorAction Stop
    if ($PSCmdlet.ShouldProcess($Path, "Set LogRetentionDays to $Days")) {
        $settings.LogRetentionDays = $Days
        $settings | ConvertTo-Json -Depth 5 | Set-Content -LiteralPath $Path -ErrorAction Stop
    }
}
Set-ConfigRetention -Path '/home/user/settings.json' -Days 30 -WhatIf

SupportsShouldProcess supplies the common parameters, and the guard controls the actual write. A preview leaves the file bytes intact; an approved call updates just the managed setting.