Welcome to the next post in my Next-Level Scripting series where I show you the PowerShell scripting techniques that take your scripts to the next level – a level defined by concise, well-written code that conforms to best practices and uses the built-in tools in PowerShell whenever possible to handle common scripting tasks.
In today’s post we’re going to look at the switch parameter in PowerShell. In Part I of the parameters series, we looked at how parameters can help us with obtaining information from the person running our script without using Read-Host. In Part II we’re going to look at a special type of parameter called the switch parameter.
What Does It Do?
The switch parameter allows you to deal with true/false situations in a far more elegant way than the traditional approach of asking the user a question. Let’s say you are writing a script to copy files to a group of computers. The script will be run against a wide variety of computers in your organization, from servers to laptops. When you’re copying to servers you are confident that they will be online but when you copy to laptops you know that some of them will be offline. You would like the option of doing a ping test before starting the copy to avoid waiting for the long timeout before the copy fails if the target computer is offline. But you also don’t want the ping test done every time you run the script. So you need a way to turn off the ping test depending on what group of computers each run of the script is targeting.
Ask and Ye Shall Receive
One approach which you might use is to ask the user a yes/no question as shown below.
| 001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 | $choice = Read-Host "Do a ping test before each copy? Enter Yes or No" if ($choice -eq "Yes") { #insert code for ping test } elseif ($choice -eq "No") { #skip ping test } else { Write-Host -ForegroundColor Red "Error - you must enter Yes or No" exit } |
Hopefully the problem with this approach is evident here. You can’t really control what the user types in so you have to check for “Yes”, “No”, and something that doesn’t match either of those. While this approach would work, it’s not the approach that a Next-Level Scripter would use.
Don’t Ask
The more elegant approach to a situation like this is to just not ask. You might be wondering, “So if we don’t ask, how will we know what to do?” The answer is to use the switch parameter as shown below.
| 001 002 003 004 | Param ( [switch]$pingTest ) |
If the param block above is making you go “Huh?” I recommend you take a look at Part I of this series. If you’re still with me, let’s move on to the switch parameter inside our param block. (You would need more parameters than this to get things like which computers to target but to keep things simple I’m only including the switch parameter.)
What we have done here is allow the script, called New-FileCopy.ps1 to be run in two ways:
| 001 002 003 004 005 | # Method 1 - Skip the ping test C:\Temp\New-FileCopy.ps1 # Method 2 - Do the ping test C:\Temp\New-FileCopy.ps1 -pingTest |
If we run the script as shown in method 1, the variable pingTest will be set to $false. On the other hand, if we run it as shown in method 2 the variable pingTest will be set to $true. By now you are hopefully looking with disdain on the first way I demonstrated for getting this information using Read-Host and looking with admiration at the beauty and simplicity of achieving the same result with the switch parameter.
Now all we need to do is check if pingTest exists and act accordingly. EFFICIENCY TIP – you want to write the most elegant code possible, right? When it comes to true/false variables you don’t need to check if the variable is set to True or False, you just need to check it with a simple if statement. Compare the two ways of doing it shown below to see what I mean. The result is the same but I will always think to myself, “This person is a Next-Level Scripter” when I see the check done the second way.
| 001 002 003 004 005 006 007 008 009 010 | Param ( [switch]$pingTest ) #Waste of space to do it this way if ($pingTest -eq $true) {Write-Host "You chose to do the ping test"} #Do it this way and you save having to type 9 extra characters! if ($pingTest) {Write-Host "You chose to do the ping test"} |
And that’s all there is to it…with one simple line of code we’ve created our pingTest variable and can easily control whether it is set to True or False. What’s more, it can’t be tripped up by someone typing “Yess” by mistake!
Conclusion
We’ve taken our ping yes/no check to the next level in this post by using the built-in switch parameter to control whether the ping test is performed. When compared to the first method I demonstrated which used Read-Host and prompted the user for a response, the Next-Level method is significantly more simple and more robust as there is minimal code involved and no reliance on a user typing the correct response.
No comments:
Post a Comment