As we use PowerShell Toolmaking to automate more tasks, most of us eventually find ourselves reinventing the wheel. We write a script to do task X, another to do task Y, then task Z comes around. A few weeks go by and we begrudgingly write another script to do task X again. This is because scripts have traditionally been treated as disposable. It's not until you repeat this process a few times that you realize you need to take your scripting skills to another level. It's time to build PowerShell "tools" rather than disposable scripts.

Tools vs. Scripts

What do I mean by "tools"? I'm referring to using PowerShell Toolmaking to write a piece of code that's built for reuse and modularity. It's a script or function that's built in a way that allows you to quickly pass different parameters to make it work differently. For example, imagine you need to make a script that creates an Active Directory user and a home folder. A disposable script called New-UserProvision.ps1 might look something like:

New-AdUser -Name abertram -Path 'OU=MyUsers,DC=lab,DC=local'
New-Item -Path '\\fileserver\Home\abertram' -Type Directory

It gets the job done, but what happens when you want to perform this task again? You'll have to change the Name and Path parameters for New-AdUser and also the Path parameter for New-Item. And you'll have to do this every ... single ... time. To use a script like this in the long term is not feasible. The script will need to be refactored to be reusable.

The most important distinction between a simple script and a tool is reusability. One of the easiest ways to make a script or function more reusable is to add parameters. Parameters are ways to set placeholders for things that might change in the future. Parameters allow you to modify the functionality of the script without actually changing the script.

How to Build a Tool Using Parameters

Let's use our previous example again, only this time we're going to create a tool rather than a disposable script. First, we'll need to decide which parts might change in the future. We know that we'll always want to create an AD user and create a home folder for every user. Our command references are not going to change. What might change are things like the username, the path where the user is created in AD, and the home folder path. These are the items you should convert into parameters.

We create parameters by setting up a parameter block at the top of the script, followed by one or more individual parameters. A basic parameter can be defined as a simple variable as seen below. This is what we're going to focus on in this article, but parameters can get much more advanced.

param ($Username,$OUPath,$HomeFolderPath)

You can see that I've created a variable for each of the pieces that I believe might change when running this code for other users.

I can now replace the static entries in the script with the parameter variables.

New-AdUser -Name $Username -Path $OUPath
New-Item -Path $HomeFolderPath -Type Directory

As it is, this code isn't going to do much. We can't just execute it and expect it to do everything it did before. It must be run with the parameter values filled in to do anything. Rather than just running the script New-UserProvision.ps1, we now must execute it and pass the parameters at run time.

.\New-UserProvision.ps1 -Username abertram -OUPath 'OU=MyUsers,DC=lab,DC=local' -HomeFolderPath '\\fileserver\Home\abertram'

It requires a little more work to execute it, but you don't have to change anything in the script if you want to provision a new username. Simply pass different values to the parameters. Also, by parameterizing your script, you can provision many users at once, such as from a CSV file.

@(Import-Csv -Path C:\Users.csv).foreach({
    .\New-UserProvision.ps1 -Username $_.Username -OUPath $_.OUPath -HomeFolderPath $_.HomeFolderPath
})

The snippet above would create a new user and home folder for every row in the C:\Users.csv file. This wouldn't be possible if we had to manually edit each item every time.

If you'd like to dive deeper into this concept and get a demonstration of some real-world tools that have been developed, check out my recorded webinar Building Tools with PowerShell.

Join the Jar Tippers on Patreon

It takes a lot of time to write detailed blog posts like this one. In a single-income family, this blog is one way I depend on to keep the lights on. I'd be eternally grateful if you could become a Patreon patron today!

Become a Patron!