All advanced functions and cmdlets have a built-in switch argument called the PowerShell WhatIf parameter. When used, the command does not really run; instead, it reports to the console the expected effect of the operation.
The WhatIf option is available for all advanced functions and cmdlets. In this post, I will use the Get-Service, Stop-Service, and New-Item cmdlets to illustrate this parameter.
How to Check If Powershell -WhatIf Script is Supported?
This guide works with PowerShell versions 5.1 and higher and only makes use of local computer resources. Ideally, you should have installed your preferred IDE or ISE for PowerShell.
1. Get-Command usage
By supplying the Syntax option, the Get-Command command allows you to view command metadata. WhatIf is supported if you see a -WhatIf reference.
Get-Command <CommandName> -Syntax
2. Tab completion is used
Using tab-completion, you can also see if the WhatIf parameter is supported. In a PowerShell terminal, just enter the command you want to check, followed by a space, dash, “Wh,” and the tab key.
You can tell that command has the WhatIf parameter if WhatIf appears.
PS> <CommandName> -Wh[tab]
Method to use PowerShell Whatif Parameter?
The WhatIf parameter can be utilized in a wide variety of ways. You’ll discover in this part how to use built-in cmdlets to start using the PowerShell Whatif parameter right away.
1. Creating a New File
The PowerShell Whatif parameter is a feature of all cmdlets, including New-Item. In this example, you will create a file called file.txt in the same working directory using the New-Item cmdlet.
The command listed below would produce a file with the name file.txt.
New-Item -ItemType File -Path .\file.txt
But what if this operation creates a file that, if generated incorrectly, would pose a problem? No issue. The PowerShell Whatif parameter can be added at the end.
New-Item -ItemType File -Path .\file.txt -WhatIf
2. Stopping a Windows Service
The WhatIf option is likewise compatible with the Stop-Service cmdlet. With the Stop-Service command, you are obtaining a list of the first five services and halting them.
Instead, you only receive an output message informing you of the services that the Stop-Service cmdlet would have terminated in the PowerShell console.
(Get-Service)[0..4] | Stop-Service -WhatIf
Changing Powershell -WhatIf parameter
When used with a cmdlet or advanced function, the PowerShell Whatif parameter just simulates the operation. At the command level, you were having an impact on WhatIf behavior.
By changing the automatic variable $WhatIfPreference, it is also possible to control the WhatIf behavior at a higher level that impacts all commands.
The Boolean (true or false) describes the $WhatIfPreference variable. Only True or False is an option. It is set to False by default, which means that unless modified at the command level, PowerShell Whatif support is disabled for all commands. If True, any commands that support it, whether they explicitly use the PowerShell WhatIf parameter or not, will operate in “WhatIf mode.”
By setting the value of $WhatIfPreference to True with $WhatIfPreference = $true, you can verify this. Using New-Item without the WhatIf parameter now behaves as though the parameter was supplied.
How to use the ShouldProcess in the script?
ShouldProcess has two purposes: describing what it will do and determining if it can accomplish it without causing damage.
Since we give ShouldProcess a target and an action, the description portion will execute immediately. But the second part, which is optional but can make your scripts far more resilient, can be trickier.
The tests that you run can be simple or complicated, checking everything from write permissions to returning fake data after a successful write.
Examples of a function that produces five files are given below, but the latter additionally runs tests to verify that you have permission to write to the specified directory if PowerShell Whatif is provided.
class="language-powershell">Function TestFiles
{
[CmdletBinding(SupportsShouldProcess)]
Param(
[Parameter(Mandatory,ValueFromPipeline)]
[String]$Directory,
[Int]$Amount = 5
)
Begin{}
Process {
# Create $Amount number of files
1..$Amount | ForEach-Object {
$Target = Join-Path -Path $Directory -ChildPath "$_.txt"
# ShouldProcess
if($PSCmdlet.ShouldProcess($Target, "Create File")){
Set-Content -Value "No content" -Path $Target
}
}
}
End {}
}
Even if you don’t have write access to C:\Windows, it displays that “Create File” is being performed. This may be deceptive, and in many instances, using ShouldProcess without verifying that it is capable of carrying out the stated activities if WhatIf is supplied can defeat the purpose of employing it.
Let’s add some additional checks to the preceding PowerShell functions by including them in an ElseIf clause that is added following the If clause that contains the call to the ShouldProcess script:
class="language-powershell">Function New-TestFiles
{
[CmdletBinding(SupportsShouldProcess)]
Param(
[Parameter(Mandatory,ValueFromPipeline)]
[String]$Directory,
[Int]$Amount = 5
)
Begin{}
Process {
# Create $Amount number of files
1..$Amount | ForEach-Object {
$Target = Join-Path -Path $Directory -ChildPath "$_.txt"
# ShouldProcess
If($PSCmdlet.ShouldProcess($Target, "Create File")){
Set-Content -Value "No content" -Path $Target
}
ElseIf($WhatIfPreference){
$TestFile = Join-Path -Path $Directory -ChildPath "testfile.tst"
Try {
[Io.File]::OpenWrite($TestFile).close()
Remove-Item -Path $TestFile -WhatIf:$False -ErrorAction SilentlyContinue
}
Catch {
Write-Warning "$Directory is not writeable!"
}
}
}
}
End {}
}
In order to verify that you have permission to write to the directory, the test that was added in this version of the function will write to a test file and then remove it.
When conducting tests with WhatIf, always use ElseIf($WhatIfPreference)code> as ShouldProcess also handles Confirms (i.e., “Do you want to run this?”). This will guarantee that the tests only execute under “WhatIf” conditions.