Hello!
I write a lot of utility scripts. Little helpers to automate repetetive work. Like going through all those YAML files and updating that one config item, or reading through all those database entries and finding the two that are messed up because of that weird bug I just found.
These scripts are usually small. I often don’t keep them very long. I also usually have to run them against multiple environments, and sometimes I have to hand them to other engineers. They need to behave predictably everywhere, and they need to be easy to read and run. They can’t be hacks that only I can use.
In my work, that means a script that takes arguments and passes them to internal functions that implement whatever I’m trying to do. Let’s say I need to find a thing with a known index, then reset it. Here’s the pattern I use in PowerShell:
[CmdletBinding()] param( [int]$Index ) function Get-Thing { [CmdletBinding()] param( [int]$Index ) return "Thing$Index" } function Reset-Thing { [CmdletBinding()] param( [string]$Thing ) # We'd do the reset here if this were a real script. Write-Verbose "Reset $Thing" } $Thing = Get-Thing -Index $Index Reset-Thing -Thing $Thing
We can run that from a prompt with the Index
argument:
./Reset-Thing.ps1 -Index 12 -Verbose VERBOSE: Reset Thing12
Some details:
- The
param()
call for the script has to be at the top. Posh throws errors if you put it down where the functions are invoked. CmdletBinding()
makes the script and its functions handle standard arguments like-Verbose
. More details here.- This uses
Write-Verbose
to send informative output to the verbose “stream”. This is similar to setting the log level of a Python script toINFO
. It allows the operator to select how much output they want to see. More details here. - As always, use verbs from
Get-Verb
when you’re naming things. - I could have written this with just straight commands instead of splitting them into
Get
andReset
functions, especially for an example this small, but it’s almost always better to separate out distinct pieces of logic. It’ll be easier to read if I have to hand it to someone else who’s not familiar with the operation. Same if I have to put it aside for a while and come back to it after I’ve forgotten how it works.
This is my starting point when I’m writing a helper script. It’s usually enough to let me sanely automate a one-off without getting derailed into full-scale application development.
Happy scripting,
Adam
Need more than just this article? We’re available to consult.
You might also want to check out these related articles: