With the Set-StrictMode cmdlet you can turn PowerShell’s Strict Mode on, which ensures that you follow best practices in your script. Here, you’ll learn the differences between Strict Mode versions 1.0 and 2.0.

By default, PowerShell is pretty lenient with certain programming rules that are considered bad practice. This can be both a blessing and a curse: a blessing in that it allows some flexibility when developing a script or learning PowerShell for the first time, but a curse in that certain classes of bugs and poor design choices can creep into your code and make troubleshooting a nightmare. Leaning how and why to use Strict Mode will help you level-up your PowerShell development skills and stamp out those pesky bugs.

Introduction

So, what is PowerShell’s Strict Mode? Essentially, Strict Mode disables a few programming rules that PowerShell normally lets us use that go against best practices. Coding with these best practices in mind can help prevent bugs in your script at the cost of a little flexibility, especially during development. When Strict Mode is enabled, violating these rules will produce terminating errors in our scripts. Using the cmdlet Set-StrictMode, Strict Mode can be set to the following:

  • Off
  • Version 1.0
  • Version 2.0
  • Version Latest

This is a very simple cmdlet as far as parameters go. We only have two parameters to work with, Off and Version.

# Disable strict mode
Set-StrictMode -Off

# Set strict mode to version 1.0
Set-StrictMode -Version 1.0

# Set strict mode to version 2.0
Set-StrictMode -Version 2.0

When Strict Mode is set to Off (the default state), PowerShell operates with the most lenience and flexibility.

Setting Strict Mode to Version 1.0 will prohibit you from referencing variables that have not been initialized.

Strict Mode to Version 2.0 will also prohibit you from referencing initialized variables, in addition to prohibiting references to non-existent properties on objects, function calls using the syntax for calling methods, and variables without names.

When Strict Mode is set to Version Latest, it’ll use the strictest version available. This is currently Version 2.0, but if a newer version is added to PowerShell in the future, this setting would automatically use that newer version instead of Version 2.0.

When Strict Mode is enabled, it affects the current scope, and any child scopes. This means that if a PowerShell script or module turns on Strict Mode, it won’t affect the global scope, nor will it break other scripts or modules that aren’t children of the scope where it was set.

Now let’s dive a little deeper into what these rules mean, and take a look at some examples.

Strict Mode version 1.0

You can enable Strict Mode version 1.0 by running:

Set-StrictMode -Version 1.0

Version 1.0 prohibits referencing uninitialized variables. In practice, this looks like:

Set-StrictMode -Off
$foo
Set-StrictMode -Version 1.0
$foo
Using Strict Mode Version 1.0

Using Strict Mode Version 1.0

You can see that with Strict Mode turned off, PowerShell has no problem with us referencing a non-existent variable, but will pitch a fit when Strict Mode is set to Version 1.0.

Strict Mode version 2.0

You can enable Strict Mode version 2.0 by running:

Set-StrictMode -Version 2.0

On top of what Version 1.0 disables, Version 2.0 also prohibits us from referencing non-existent properties on objects, calling functions using the syntax for calling methods, and using variables without names.

I’d argue that referencing uninitialized variables and non-existent properties on objects are much more common than the latter two rules.

Referencing non-existent properties on objects is a common bug you’ll encounter when developing PowerShell scripts or modules, and will lead to a fair amount of hair pulling. Since everything in PowerShell is an object, we tend to make many references to properties of those objects, meaning typos are inevitable. Setting Strict Mode to Version 2.0 will cause them to produce a terminating error rather than nothing at all:

Set-StrictMode -Version 2.0

$myObj = [PSCustomObject]@{
    Property1 = 'foo'
    Property2 = 'bar'
}
$myObj.Property1
$myObj.Propery2
Referencing a non existent property with strict mode version 2.0

Referencing a non existent property with strict mode version 2.0

Now, let’s look one of these lesser-known rules. Strict Mode version 2.0 prohibits calling functions using method syntax:

Set-StrictMode -Off

function Add-Numbers {
    param(
        $Num1,
        $Num2
    )
    $Num1 + $Num2
}

Add-Numbers(32, 10)

Set-StrictMode -Version 2.0
Add-Numbers(32, 10)

Add-Numbers -Num1 32 -Num2 10
Calling a function like a method in strict mode version 2.0

Calling a function like a method in strict mode version 2.0

Without version 2.0 Strict Mode enabled, PowerShell will treat (32,10) as an array, and pass to the first parameter (Num1). Num2 will not have a value so nothing will be added. I personally have not seen this syntax used in the wild, but it is certainly a possibility, and a bad practice nonetheless.

Subscribe to 4sysops newsletter!

Conclusion

As demonstrated in these examples, using PowerShell’s Strict Mode can help eliminate several potential sources of bugs in your code. When developing a new script or module, it’s a good idea to put Set-StrictMode right at the top to help nudge you toward using the best practices and save you some troubleshooting and stress down the road.

avataravatar
4 Comments
  1. Jim Ruby (Rank 2) 5 years ago

    I have

    Set-PSDebug -Strict

    at the start of my $Profile, which is pretty much the same as

    Set-StrictMode -version 1.0

    (I used Set-PSDebug because I didn’t know about Set-StrictMode back then 🙂 )

    This has saved me significant amounts of time that I used to waste tracking down mis-typed variable names.  After reading the article I’ve updated $Profile to use strict mode version 2.0, that’ll help out even more.+

    To the readers:  Check out Set-PSDebug if you haven’t – it can be set to display variable assignments, function calls, etc when the script runs. Sometimes too much information is presented, but if you have a problem code section, turn it on for that section then turn it off afterward until you get the kinks worked out.

    avataravatar
  2. Lars Panzerbjrn 5 years ago

    If you are completely honest, how many of your scripts actually start with Set-StrictMode?

    Set-Strictmode is a great theoretical idea, and I would probably use it if I could choose what I was strict about, but there is a reason why no scripts on the technet gallery uses it, even from people who otherwise recommend using Set-StrictMode…

    I was curious, so I downloaded a bunch of scripts from various”professional powershellers” (I think they are at least), and not one of the scripts had it.

Leave a reply

Your email address will not be published. Required fields are marked *

*

© 4sysops 2006 - 2023

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account