PowerShell Scripts with WhatIf

Sometimes you want to simulate the execution of a PowerShell script. Instead of actually doing the things defined in the script you just want to see what would have been done. Many Cmdlets understand the parameter -WhatIf. If you use it e.g. when creating a directory it actually will not be created. Instead you get a message describing what would have been done:

1
New-Item -ItemType Directory -Name "test" -Path "c:\temp" -WhatIf
PS C:\> New-Item -ItemType Directory -Name "test" -Path "c:\temp" -WhatIf
What if: Performing the operation "Create Directory" on target "Destination: C:\temp\test".

In your own script you can use -WhatIf with the help of CmdletBinding.

1
2
3
4
5
6
[CmdletBinding(SupportsShouldProcess=$True)]
Param()

Get-ChildItem -Directory "c:\temp"
Out-File -FilePath "c:\temp\Test-WhatIf.log" -InputObject "Text" -Encoding ASCII
New-Item -ItemType Directory -Name "test" -Path "c:\temp"

The script is named Test-WhatIf.ps1. If you specify the parameter WhatIf all Cmdlets supporting it will be executed as if WhatIf was specified within your code. The Cmdlet Get-ChildItem e.g. does not support WhatIf. So the content of the directory gets listed.

PS C:\> ./Test-WhatIf.ps1 -WhatIf

    Directory: C:\temp

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----        19.05.2016     14:58            directory1
d----        11.07.2016     10:22            directory2
d----        06.07.2016     15:56            directory3
d----        19.05.2016     15:12            directory4
What if: Performing the operation "Output to File" on target "c:\temp\Test-WhatIf.log".
What if: Performing the operation "Create Directory" on target "Destination: C:\temp\test".

Maybe you want some Cdmlets to be executed even if the script was started with WhatIf. In this case you can set -WhatIf for this Cmdlet to $False:

1
2
3
4
5
6
[CmdletBinding(SupportsShouldProcess=$True)]
Param()

Get-ChildItem -Directory "c:\temp"
Out-File -FilePath "c:\temp\Test-WhatIf.log" -InputObject "Text" -Encoding ASCII -WhatIf:$False
New-Item -ItemType Directory -Name "test" -Path "c:\temp"

This time the script write the text to the file but does not create the directory.

PS C:\> ./Test-WhatIf.ps1 -WhatIf

    Directory: C:\temp

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----        19.05.2016     14:58            directory1
d----        11.07.2016     10:22            directory2
d----        06.07.2016     15:56            directory3
d----        19.05.2016     15:12            directory4
What if: Performing the operation "Create Directory" on target "Destination: C:\temp\test".
PS C:\> Get-Content "c:\temp\Test-WhatIf.log"
Text

You might also want to check within the script if it was executed with -WhatIf or without. You can use the variable $WhatIfPreference for this:

1
2
3
4
5
6
7
8
[CmdletBinding(SupportsShouldProcess=$True)]
Param()

If ($WhatIfPreference) {
    Write-Host "executed with WhatIf"
} Else {
    Write-Host "executed without WhatIf"
}
PS C:\> ./Test-WhatIf.ps1 -WhatIf
executed with WhatIf

PS C:\> ./Test-WhatIf.ps1
executed without WhatIf