How to build the appropriate PowerShell parameters
What if you had a single place where you could manage data, and the tool you used would automatically take care of all the translation in the background?
June 22, 2015
A beginner new to writing PowerShell scripts might simply open up his favorite PowerShell script editor and just start coding out what he needs to do. He may have specific requirements such as create Active Directory (AD) user accounts, setting permission on an Exchange mailbox or perhaps moving some files around. Whatever the case, he has specific requirements: create AD user accounts from the C:Users.csv file, give each user full access to the shared mailbox ConferenceRoom, move all files from \SERVER1c$SomePath to \SERVER2d$SomeOtherPath.
These requirements are fictional but realistic. Someone doesn’t typically sit down and write a PowerShell script for the fun of it. They typically have a specific purpose to do so. They have a problem that can be solved with automation and they have chosen PowerShell for the solution. Let's see what would happen if I write this fictional script with some pseudocode and call it DoSomething.ps1:
## Read the CSV file to create the AD users$CsvOutput = Import-Csv -Path C:Users.csvforeach ($User in $CsvOutput) {New-AdUser -Name $User ## blah blah blahSet-ExchangeMailboxPermission -Name $User -Permission FullPermission -Mailbox ConferenceRoom}Move-File \SERVER1c$SomePath \SERVER2d$SomeOtherPath
I run it like this: & .DoSomething.ps1 and it works! Granted, this code isn’t actually going to work but let’s just say it did. Do you see anything wrong here? It solves the problem and does everything we want it to, right? Yes. But, this is not the best way to write a PowerShell script. Can you spot the reason why? No, it’s not because I didn’t use the pipeline or didn’t use the right kind of loop. It was because this script is static and has no parameters.
Every script has variables and I’m not talking about actual PowerShell variables. Every piece of code regardless of the language has "business logic" variables. These are the variables that may change over time. Today you might be importing a CSV file from C:Users.csv but what about tomorrow or the next day? Do you really want to ensure that a CSV is located in C:Users.csv every time you want to run this script? Is that ConferenceRoom mailbox always going to be the same name? Probably not. These are your "business logic" variables and should be used as parameters to your script.
Parameters are simply ways you can match up actual PowerShell variables to your "business logic" variables. Using well thought out parameters in a script will allow you to not only run this script today but you can run it tomorrow even if circumstances change -- and you won't have to modify the actual guts of the script. It’s a way of putting all those things that might change over time in one spot so you can easily just tweak a few lines instead of hunting through the entire script doing a mass find and replace.
Let’s use that example I just described above and first pick out the "business logic" variables. Can you spot them? If you’re new to this it might be a little difficult at first and every script is different but practice makes perfect. In this example, our "business logic" variables are the CSV file path, the permission to the mailbox, the mailbox name, the source location for the files we’re copying and the destination location. You could argue others exist but we have to put on the training wheels before peddling away.
With that being said, let’s put some simple parameters to this script and replace all those "business logic" variables with actual PowerShell variables which are representing the parameter values.
param($UsersCsvFilePath,$MailboxPermission,$MailboxName,$SourceFileFolderPath,$DestFileFolderPath)## Read the CSV file to create the AD users$CsvOutput = Import-Csv -Path $UsersCsvFilePathforeach ($User in $CsvOutput) {New-AdUser -Name $User ## blah blah blahSet-ExchangeMailboxPermission -Name $User -Permission $MailboxPermission -Mailbox $MailboxName}Move-File $SourceFileFolderPath $DestFileFolderPath
Now, instead of executing the script with no parameters as I did earlier I now execute it like this: & .DoSomething.ps1 -UsersCsvFilePath C:Users.csv -MailboxPermission ‘FullPermission’ -MailboxName ‘ConferenceRoom’ -SourceFileFolderPath ‘\SERVER1c$SomePath’ -DestFileFolderPath \SERVER2d$SomeOtherPath
There you have it. It’s much better now but it’s really not that much different. You might ask why it’s better since I just added a line at the top and replaced a few "business logic" variables with actual PowerShell variables. The reason is it’s ease of use and reusability. In this tiny example, you may not see it as much but crack open a 10,000 line script and it will be painfully obvious.
Spotting the "business logic" variables and replacing them with parameters will allow your script to adapt to multiple scenarios. Hardcoded, static entries like that in the first example are bad practice and should never be done unless you know for a fact you’ll never use the script again. Make it a point from now on to spot those instances that actually should be a parameter and get those parameters built. There’s no limit to the amount of parameters you can have so I suggest using as many as you need.
About the Author
You May Also Like