PowerShell parameters: Controlling the input of your scripts

When coding your PowerShell scripts, an essential part is the definition and validation of the parameters that are required to make it run properly. PowerShell has several options to help the IT professional control the input and save tons of code from being validated during the execution time. We are going to offer some simple scenarios that we can address at the parameter section of the script. Although we are not going to code anything within the script, let’s use a simple scenario that we have a script to protect Azure VMs, and we want the user to provide the virtual machine name and if he or she wants to protect or restore any given VM.

We could create a script for every action (backup and restore). However, both scripts would share some standard functions, and it is much easier and practical to maintain a single script that performs both activities in the same code.

Getting started with your Param() section

The first thing that we have to do is to define the Param() section. This section must be at the top of your script. Our design is that besides the VM name, the user has to provide either backup or restore.

We can start simply by defining the name of the parameters and defining their types. In the example below, we want a string for the $VMName, and protect and restore will be a switch type.

We can see how it feels to the end-users when using switch and string. When I try to pass -VMName without any string, the script throws me an error. If I do the same thing for a switch parameter (-protect in our case), everything goes well.

Param (
[string]$VMName,
[switch]$protect,
[switch]$restore
)

Forcing a parameter

In our script, we must know the VM name. Otherwise, we can’t even start our operations. We can force a parameter to be mandatory by performing a slight change at the beginning of the line that we have defined the $VMName in the previous section.

Param (
[Parameter(Mandatory=$true)][string]$VMName,
[switch]$protect,
[switch]$restore
)

Providing help to the end-user

If you are a good person and want to perform a good deed for the users of your code, you can use the HelpMessage to provide a short explanation of what you are looking for on those specific parameters. The updated code is listed below.

Param (
[Parameter(Mandatory=$true,HelpMessage="The VM Name in the current Azure subscription")][string]$VMName,
[switch]$protect,
[switch]$restore
)

As an end-user, when you run the script, and no parameters are provided, the VMName will be required (because we configured as mandatory). However, we can type !? and the HelpMessage that we configured will be displayed. The script code and the action that we have just described is depicted in the image below.

Using alias to support end-user requirements

Some users have their way to refer to an object, and you can accommodate those types of requests using Alias. We can assign several names that we believe our end-users may use instead of VMName as a parameter.

In our example below, I added virtualmachine, machine, alien and ChupaCabra. As long as some of those are typed, they are all going to be stored in the $VMName variable.

Note: The alias does not show up on the auto-complete. When the user types and hits <tab>, only the parameter names will be displayed.

Param (
[Parameter(Mandatory=$true,HelpMessage="The VM Name in the current Azure subscription")][Alias("VirtualMachine","Machine","Alien","ChupaCabra")][string]$VMName,
[switch]$protect,
[switch]$restore
)
Write-Host $VMName

Validating the PowerShell parameter on the fly

We can use smart validations using ValidateScript attribute. Let’s say that we don’t have a VM name with less than five (5) characters, we can use [ValidateScript({($_).Length -gt 4})] to validate that during the input of the parameters, and that will save us some line of code in the script to validate down the road.

We are adding too many attributes to our $VMName, so an excellent way to organize is to add one attribute per line. The content is the same that we have been using, just in a different format.

Param (
[Parameter(Mandatory=$true,HelpMessage="The VM Name in the current Azure subscription")]
[Alias("VirtualMachine","Machine","Alien","ChupaCabra")]
[ValidateScript({($_).Length -gt 4})]
[string]
$VMName,
[switch]$protect,
[switch]$restore
)
Write-Host $VMName

A simple and even cooler example is to combine with real-time validation of your environment in Microsoft Azure. In the code below, we are checking to see if the VM actually exists. If it does not, then we don’t need to even bother to execute the script.

Param (
[Parameter(Mandatory=$true,HelpMessage="The VM Name in the current Azure subscription")]
[Alias("VirtualMachine","Machine","Alien","ChupaCabra")]
[ValidateScript({Get-AZVM -Name ($_)})]
[string]
$VMName,
[switch]$protect,
[switch]$restore
)
Write-Host $VMName

Validating the switch parameters

At this point, we have a robust $VMName in-place. Our next step is to understand what the end-user is providing for backup/restore options.

We can take advantage of $PSBoundParameters to control what the user is doing from the command line. We added as the first line of our script to see what kind of information we can gather when using it. As you can see in the image below, every parameter used will be added to the hash table with its value.

Param (
[Parameter(Mandatory=$true,HelpMessage="The VM Name in the current Azure subscription")]
[Alias("VirtualMachine","Machine","Alien","ChupaCabra")]
[ValidateScript({($_).Length -gt 4})]
[string]
$VMName,
[switch]$protect,
[switch]$restore
)
$PSBoundParameters

If we know that we have a hash table with all the data that is coming from the command line. We know for a fact that one parameter is going to be the VMName. We forced that as mandatory, so the user can technically add another two parameters.

If we see the number of parameters higher (gt meaning Greater Than) two, the assumption is that the end-user entered -protect and -restore. We performed all possible scenarios, and we see the results in action.

If the user tries to use two parameters and leaves the VMName parameters out of the picture, the mandatory option will protect us.

We can apply the same logic and figure out the path in our script based on the switch decided by the end-user. In the image below, we can see how we made the input of our script airtight with a few lines of code.

Param (
[Parameter(Mandatory=$true,HelpMessage="The VM Name in the current Azure subscription")]
[Alias("VirtualMachine","Machine","Alien","ChupaCabra")]
[ValidateScript({($_).Length -gt 4})]
[string]
$VMName,
[switch]$protect,
[switch]$restore
)
If ($PSBoundParameters.Count -gt 2) {
Write-Host "Too many parameters"
}
Write-Host
If ($PSBoundParameters.Keys.Contains("restore")) {
Write-Host "Restore code..."
}
If ($PSBoundParameters.Keys.Contains("protect")) {
Write-Host "Protect code..."
}
Write-Host

PowerShell has way more attributes to help validation, but here we covered the main ones that I believe are important to have in your toolbox when coding your scripts.

Featured image: Shutterstock

Anderson Patricio

Anderson Patricio is a Canadian MVP in Cloud and Datacenter Management, and Office Server and Services, besides of the Microsoft Award he also holds a Solutions Master (MCSM) in Exchange, CISSP and several other certifications. Anderson contributes to the Microsoft Community with articles, tutorials, blog posts, twitter, forums and book reviews. He is a regular contributor here at Techgenix.com, MSExchange.org, ITPROCentral.com and Anderson Patricio.org (Portuguese).

Share
Published by
Anderson Patricio

Recent Posts

Diebold Nixdorf ATMs targeted by jackpotting attacks

ATM manufacturer Diebold Nixdorf says its European machines are being hit by jackpotting attacks, where…

13 hours ago

Allow a home computer to connect to your Azure SQL server/database

In these days where remote computing has become crucial, you can connect your home computer…

17 hours ago

Migrating to Microsoft 365? Get the ball rolling with a trial tenant

Many companies still using Exchange Server are thinking of moving to Microsoft 365. You can…

20 hours ago

wpDiscuz WordPress plugin: Critical vulnerability found and patched

Users of the wpDiscuz interactive comment WordPress plugin should implement a new patch as soon…

2 days ago

Data lifecycle management: Policies and procedures for security and compliance

With the amount of electronic information consistently growing, data lifecycle management is crucial for compliance…

2 days ago

Deploy Windows from the cloud to on-premises hardware? Yes, you can

Wouldn’t it be nice if you could deploy Windows from the cloud while sipping an…

5 days ago