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.
Adam Bertram is an independent consultant, technical writer, trainer and presenter. Adam specializes in consulting and evangelizing all things IT automation mainly focused around Windows PowerShell. Adam is a Microsoft Windows PowerShell MVP, 2015 powershell.org PowerShell hero and has numerous Microsoft IT pro certifications. He is a writer, trainer and presenter and authors IT pro course content for Pluralsight. He is also a regular contributor to numerous print and online publications and presents at various user groups and conferences. You can find Adam at adamtheautomator.com or on Twitter at @adbertram.