James Thew - Fotolia

Tip

Test and confirm functions with PowerShell parameters

Windows PowerShell functions support parameters that can prevent scripts from being run accidentally and simulate the outcome of the function.

Windows PowerShell scripting can save you tons of time. PowerShell can automate or manage just about everything within the Microsoft infrastructure from the command line. PowerShell scripts can be simple and used to enumerate a set of files or registry keys. Alternatively, the script can be large with hundreds of lines to produce a detailed server inventory report with bright colors and proper formatting. These are examples of operations where PowerShell goes out and reads various configuration items. PowerShell does not change anything; it simply reports the current state. These operations are typically represented by cmdlets that have the verb Get.

PowerShell also can perform various add, remove and modify operations. Cmdlets with verbs such as New, Remove and Set represent these actions. If you have a high level of authority in your environment and some PowerShell knowledge you could save a lot of time by automating tasks -- or cause problems when that automation goes wrong. One of my favorite phrases is "automation is a good way to fail at scale" which couldn't be truer. Fortunately, there are PowerShell parameters that can prevent accidental changes to scripts.

In this article, we'll cover how you can build functions to produce reports of what would have happened if your function ran. This is called WhatIf support. We'll also cover how to create prompts for Windows PowerShell functions to ask you if certain actions are acceptable before they are executed.

An example PowerShell function

Let's start with a function that removes a fictional virtual machine (VM). You might have a function already built like this that removes a VM and does some cleanup as well.

It has a single parameter called $VMName that represents the name of the VM you'd like to remove. As soon as you run Remove-MyVM –VMName VM123 it will remove that VM immediately. It cleans up that VM just as you'd like.

Function Remove-MyVM

{

     [CmdletBinding()]

     param(

           [Parameter()]

           [string]$VMName

)

 

Remove-VM –VM $VMName

}

One day, you get distracted and accidently pass the wrong VM name to your function and hit enter before thinking.

Remove-MyVM –VMName SUPERIMPORTANTVM

That VM is now gone before you know it. How could this have been prevented? We've got two different methods.

Using WhatIf support

If you have a high level of authority in your environment and some PowerShell knowledge you could save a lot of time by automating tasks -- or cause problems when that automation goes wrong.

The first way this could have been prevented is by building in WhatIf support. This requires two tasks: placing a keyword called SupportsShouldProcess into your function to make it "whatif aware" and placing an if/then statement inside of your function to determine if it should execute the task or report what it would have done.

Function Remove-MyVM

{

    [CmdletBinding(SupportsShouldProcess)]

    param(

         [Parameter()]

         [string]$VMName

    )

    if ($PSCmdlet.ShouldProcess("VM $VMName",'Remove')) {

        Remove-VM –VM $VMName

    }       

}

By incorporating these two components into the function, you now have the ability to use the –WhatIf parameter on this function to see what it would do before changes are made.

Add the WhatIf parameter to a function
Figure A. The WhatIf parameter tests a function before any changes are made.

 

You can see that simply by using –WhatIf as a parameter, it now gives me a message of what it would have done if I had not used the parameter. The remove and VM MYVM strings both came from the PowerShell parameters used in with the ShouldProcess() method above.

Remove-MyVM –Confirm

As another fail-safe, PowerShell supports a –Confirm parameter when using the SupportsShouldProcess keyword. By making no changes to our function, we can use this Confirm parameter; this time we are given the option to proceed versus with the WhatIf parameter, which gave no choice.

Confirm an action with the Confirm parameter
Figure B. The Confirm parameter prompts you to perform an action.

Using the Confirm parameter prompts you every time, but you must remember to use the Confirm parameter. What if you do not trust yourself and want to confirm every time? You can do this by setting the potential impact that your function has and weighing that value against what the current threshold is.

To do this, your function must have an impact higher than what's currently set with the $ConfirmPreferences variable. If the impact is greater, it will prompt you automatically. If lower, it will proceed on through.

You can see here, my $ConfirmPreferences variable is set to High.

 

ConfirmPreference variable set to High.
Figure C. Set the ConfirmPreference variable to set up an automatic prompt.

This means my function must have an impact of High to be automatically prompted. To set this impact level, I can use the ConfirmImpact keyword and set it to High.

Function Remove-MyVM

{

    [CmdletBinding(SupportsShouldProcess,ConfirmImpact = 'High')]

    param(

         [Parameter()]

         [string]$VMName

    )

    if ($PSCmdlet.ShouldProcess("VM $VMName",'Remove')) {

        Remove-VM –VM $VMName

    }

}

I now can run my function without the Confirm parameter, and you'll see that I will automatically get prompted.

A function running without the Confirm parameter.
Figure D. Run the Remove-MyVM function without the Confirm parameter.

This is because the impact of my function is set at or higher than what $ConfirmPreference is, so it will automatically prompt me.

As you can see, the WhatIf and Confirm PowerShell parameters can save you from yourself. You just have to remember to add that support into your PowerShell functions ahead of time. Although we covered most of what these two useful features provide, you can learn every aspect of WhatIf and Confirm including walkthrough and demos in the clip Playing it Safe with WhatIf and Confirm in my Pluralsight course Building Advanced PowerShell Functions and Modules where you'll also learn about $WhatIfPreference and some other useful tips.

Next Steps

How to upgrade to PowerShell version 5

Underrated PowerShell 5 features

Changes to PowerShell 5.0

Dig Deeper on Microsoft messaging and collaboration