Keeping You Honest in PowerShell with Set-StrictMode
Sometimes we need a nanny to make sure our scripts are on the up and up.
- By Adam Bertram
There are times when we all get lazy as we're writing PowerShell scripts. Maybe it's because it's the end of the day and we're just shot. We're tired and just don't care as much about our code as we did earlier in the day. It happens. This kind of behavior is to be expected even from the most diligent scripter out there. We care about writing good code but sometimes our game is just a little off. Wouldn't it be nice if we had some kind of external entity that forces us to write good code regardless of the amount of sleep we had last night? It's called Set-Strictmode.
Set-StrictMode is a cmdlet in PowerShell that forces the scripter's hand. It's like your buddy looking over your shoulder all the time, calling you out on all of your sloppy code you're writing. However terrifying it might sound it's actually a good thing! Set-StrictMode forces you to adhere to PowerShell best practices by creating terminating errors which essentially stops all code execution.
Set-StrictMode can be used in the PowerShell console itself as well as scripts (PS1) and script modules (PSM1). It is a simple cmdlet with only two parameters which just basically turns it on and off with a variation of the degree of pickiness it enforces. First, it has an Off parameter which does exactly what you'd think it does: turns it off. Although I don't recommend this, it is an option if you just can't take it anymore.
The more important parameter is Version. This parameter allows for three different versions; 1, 2 and Latest, with each version being pickier than the next.
Let's go over quick example of the usage of Set-StrictMode. Let's say I have a variable that I haven't defined yet and try to access that variable somehow. In the below example, I'm just trying to output the value to the console with Write-Host. Notice with Set-StrictMode off it just outputs a blank line. However, when I turn it on with the latest version it immediately throws a terminating error which is a lot more obvious I shouldn't have done that.
It makes your mistakes much more clear when troubleshooting. Here's another example where I'm creating an object and tried to use a property that wasn't on that object. This time, nothing was output when I tried to read that property value but as soon as I let Set-StrictMode have its way, it immediately slapped my hand.
Set-StrictMode is not permanent like Set-ExecutionPolicy. It is only applicable in your current PowerShell session and even then does not apply globally. Set-StrictMode applies at the current scope it gets executed in as well as any child scopes. This means that if declared at the module level it will apply to all functions. If it gets declared early in a script with functions inside it will apply to the script scope as well as any functions in that script or child functions.
Set-StrictMode should be a standard for any serious PowerShell scripter. It should be in every one of your scripts as one of the first lines. I suggest you add it to the top of every script you create from now on. If you use templates it should be a line at the top of every new script you create. This tiny action will not only keep you honest but it will also teach you better coding practices so that coding with best practices in mind will become nothing but second nature.
About the Author
Adam Bertram is a 20-year veteran of IT. He's an automation engineer, blogger, consultant, freelance writer, Pluralsight course author and content marketing advisor to multiple technology companies. Adam also founded the popular TechSnips e-learning platform. He mainly focuses on DevOps, system management and automation technologies, as well as various cloud platforms mostly in the Microsoft space. He is a Microsoft Cloud and Datacenter Management MVP who absorbs knowledge from the IT field and explains it in an easy-to-understand fashion. Catch up on Adam's articles at adamtheautomator.com, connect on LinkedIn or follow him on Twitter at @adbertram or the TechSnips Twitter account @techsnips_io.