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

WordPress vulnerability puts 300,000 at risk for attack

A WordPress vulnerability that could affect 300,000 users has been identified and patched. By if admins don’t update, they remain…

1 hour ago

PowerShell jobs — because you have better things to do than wait

If you run PowerShell commands that take a while to complete, consider using PowerShell jobs, which will allow the command…

4 hours ago

Validating virtual networks rules in a Storage Account using PowerShell

Here’s a TechGenix Quick Tip on how to use PowerShell to retrieve a list of virtual network rules in a…

21 hours ago

Dell launches selection of new PCs, displays, and software

A line of new Dell PCs, with innovative tech capabilities like AI and 5G, are aimed at both personal and…

1 day ago

Exchange 2010 upgrade: Migrate or export mail to PST and start fresh?

If you’re on Exchange 2010, you will have to upgrade soon. And while starting from scratch with a new 2016…

1 day ago

How to repair PST files and import data back to Outlook or Office 365

If your business relies on Outlook, you can’t risk losing mailbox data because of PST files corruption. Here’s how to…

4 days ago