Best Practices for PowerShell Scripting (Part 2)

If you would like to read the other parts in this article series please go to:

In the first article in this series, I talked about the need for adding comments to PowerShell scripts and the importance of not going overboard with the comments. At the very end of that article I briefly mentioned that a good PowerShell script should be self-documenting, but I didn’t really go into any sort of detail regarding what I meant by that. That being the case, I want to spend some time talking about self documented scripts.

Most of the best practices for creating self documented scripts pertain to variable and function usage. PowerShell is really flexible when it comes to the variables that you can use. You can’t use spaces (or certain other special characters) in variable names and you can’t use certain reserved words, but aside from those restrictions PowerShell will let you do whatever you want for the most part. My recommendation is to take advantage of this flexibility and use really meaningful variable names.

I will be the first to admit that old habits die hard and that it can be tough to make the transition into using really good variable names. I was a child of the 80s and growing up I spent countless hours writing programs on my Radio Shack Color Computer (or CoCo as it was better known). Like so many other systems of the time, the CoCo was designed for BASIC programming and was extremely restrictive when it came to variable usage. Variables had to be either one or two characters long and if the variable would be used to store text then the variable name had to be followed with a dollar sign. The end result was that a lot of the subroutines that I wrote back then included variable declarations that looked a lot like algebraic equations. To show you what I mean, here are a couple of examples of what variable assignments looked like back then:

X=2*Y
N$=”Brien”

In the early 90s I made the transition from programming in BASIC to programming in other languages such as C++ and Pascal. In doing so, I discovered that the compilers that I was using weren’t so restrictive with regard to variable names. Like PowerShell, variables could consist of names rather than a letter or two.

At first I was completely averse to using these types of variable names. After all, I had grown up using one and two character variable names and those style names still worked, so I didn’t see any need to switch. This idea was further reinforced by some of my earlier attempts at using descriptive variable names. I found that by doing so, I had to do more typing and that debugging became a little bit more complicated because there was a greater potential for making a typo when referencing a variable. Furthermore, some of the compilers that I used back in the 90s were case-sensitive.

As I gained more experience as a programmer however, I began to understand the importance of using meaningful variable names. This was especially true for longer programs.

One of the most ambitious programs that I ever wrote while I was in school was a flight Sim with a built-in aircraft designer. That application used so many different variables that I would have run out of variable names if I had stuck to using single character variables. More importantly however, some of the mathematical formulas that I was using within the flight model were complex enough that they would have been very difficult to understand had I not used meaningful variable names. Let me give you an example of what I mean.

The formula that NASA uses to calculate wing lift is:

L = CI * ((P*V2)/2)*A

Obviously this formula could be entered into a script as is, with no problems. Even so however, it would be difficult for someone without an aerospace background to decipher what this formula is. Think about it for a moment. What are we calculating? What do the variables mean?

Things become much more intuitive when meaningful variable names are used. The formula listed above could be better expressed as:

Lift = Coefficient * ((Density * Velocity2)/2 * WingArea

As you can see, the formula becomes much easier to understand when meaningful variable names are used. Using meaningful variable names alone however, is not enough.

Another best practice for writing complex PowerShell scripts is to declare all of your variables at the top of the script. This makes it a lot easier to tell up front what variables will be used in the script and what those variables will be used for. Incidentally, I strongly recommend using comments to explain what each variable is being used for.

While I am on the subject of variables, I also recommend configuring your PowerShell scripts to use Strict Mode. I will be the first to admit that using strict mode can be frustrating if you aren’t in the habit of adhering to established PowerShell best practices. After all strict mode’s job is to trigger an error message if your script deviates from best practices. Over time however, using strict mode will make you a better programmer.

Strict mode is initiated by using a PowerShell cmdlet named Set-StrictMode. I’m not going to go into all of the specifics of using this cmdlet, but you can find the syntax here.

What I do want to explain is that when you implement strict mode for the current scope (and child scopes), it will cause PowerShell to produce a terminating error if you are using a poorly written expression, script, or script block. When strict mode is off (which is the usual PowerShell behavior) then uninitiated variables are treated as though they have a value of either zero or $null. If your script attempts to reference a non existent property then that too will return a value of $null.

Strict mode’s behavior varies depending on the version of strict mode that you reference in your script. Both version 1.0 and version 2.0 for example, prevents uninitiated variables from being used (version 2 does other things as well).

Believe it or not, there is an advantage to using strict mode beyond just adhering to best practices. If an undeclared variable is assumed to contain a value of 0 then you could end up with some incorrect calculations as the result of a simple typo. Let me show you what I mean.

Suppose for a moment that we have a variable called $X and we want to set it to be equal to 6. Now suppose that we want to check to see if $X is greater than 5, but we accidentally hit the X key twice and list the variable as $XX. Check out figure A, which shows what would happen:

Image
Figure A: PowerShell returns the wrong result because I accidentally typed the variable name incorrectly.

As you can see in the figure, PowerShell has returned a result of False even though the result “should have been” true. This happens because I typed the variable name incorrectly. If this were a complex script then this single character typo could have a ripple effect that results in a major bug.

Conversely, take a look at what happens in Figure B when I make the exact same typo, but with Strict Mode enabled. In this case, PowerShell tells me that I have done something wrong rather than just performing the calculation incorrectly.

Image
Figure B: Strict mode helps you to detect errors before they can become a major problem.

Conclusion

Variable usage plays a huge role in PowerShell scripting best practices. In Part 3 I will continue the discussion by sharing more best practices with you.

If you would like to read the other parts in this article series please go to:

About The Author

3 thoughts on “Best Practices for PowerShell Scripting (Part 2)”

  1. Hi Brien,
    While your second screenshot corrects this and matches your comments, the first one indicates that you believe “5 -gt 5” should evaluate $true..

  2. No, check it out again. I set $X = to 6. Hence $X -GT 5 should be evaluated as true. However, that screen capture shows what happens when you make a type. I purposefully used $XX rather than $X. $XX is an undeclared variable, and the evaluation of the expression is False, which is correct.

  3. Hi Brien,

    In the first of your two screen shots, you actually set “$X = 5”, which is what Jeff P was referring to.

    We get the gist of what you are saying, but he was just pointing out that technically, the ‘false’ answer returned was correct because 5 is not greater than 5.

    In your second screenshot, you did, indeed, set “$X = 6”.

    All the best!

Leave a Comment

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

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Scroll to Top