Use Strict Mode for PowerShell to Help You Write Good Code

Use Strict Mode for PowerShell to Help You Write Good Code

  • Comments 2
  • Likes

Summary: Microsoft Scripting Guy, Ed Wilson, talks about calling a method like a function and using Windows PowerShell strict mode to aid script development.

Microsoft Scripting Guy, Ed Wilson, is here. Believe it or not, the 2012 Scripting Games begin in less than two weeks! That is right, less than two weeks; it hardly seems possible. But April 2, 2012 is rapidly approaching. In one respect, preparing for the 2012 Scripting Games is much like preparing for a marathon—you begin with small distances and gradually increase intensity and distance until you approach race day. However, with the 2012 Scripting Games, it is not race day, but race two weeks. Yes, for two weeks, the 2012 Scripting Games will be front and center in the minds and hearts of thousands of scripters from around the world. Who will emerge victorious? Who will win the free pass to TechEd 2012 in Orlando, Florida? Who will appear on the PowerScripting PodCast and talk to Jeffrey Snover? Who will get to hang out with the Scripting Guy and the Scripting Wife at the Scripting Guys booth at TechEd? Who will get to write a guest blog post that chronicles a meteoric rise to fame? Well…it could be you!

The Scripting Games point out documentation white space

The Scripting Games are as much of a challenge for me as they are for you—but in a different sort of way. The product of literally thousands of hours of work by hundreds of different people, the Scripting Games is first and foremost, a logistical exercise. But right up next to that, the Scripting Games provides me with a chance to evaluate the things I have written about and to assess gapes in the content (the infamous white space). It never fails that in the ramp up to the Scripting Games, I discover some topic—either small or quite large—that I have neglected to cover. It might be during the preparation of the Study Guide, or during the selection of the emphasis topics, or even during the creation of the Scripting Games Quiz.

Today, it was none of the above—it was a comment on the 2012 Scripting Games Judging Criteria.

How do I call a method?

In one of my judging guidelines, I mentioned that it is not a good idea to call a function like a method. This is, by the way, true—you should not call a function like a method. But what does this really mean? As you probably know, a method does something. In Windows PowerShell, we always use parentheses when calling a method. This is one way that you can tell when you read the code whether the code is retrieving a property or calling a method. In VBScript script, the parentheses were optional, and at times it was literally impossible to tell whether the code called a method or retrieved a property.

At times, the name would indicate if the item was a method or a property, but not always. For example, size is a property of an object, as is color. The member setDate is likely a method that sets the date of an object, and the member formatDisk is a method that will format a disk. But what about count? Well, it is possible that count is a property that tells you how many items are in something, but at the same time count could be a method that forces an enumeration of the number of items in a collection. Therefore the name of the member does not tell me if it is a method or a property. What about the code? In VBScript script, the following code works:

colItems.count

coItems.count

In the first instance, I retrieve the count property, and in the second instance I call the count method. Don’t go cross-eyed trying to perceive the difference, they are the same. On the other hand, in Windows PowerShell, I would have the following:

$colItems.count

$colItems.count()

You can see, I add the parenthesis when I want to call a method in Windows PowerShell; therefore, the parenthesis delineate the difference between a property and a method. Let me further illustrate this technique by creating an old-fashioned COM object, and then calling a method from that COM object.

$wshShell = New-Object -ComObject wscript.shell

$wshShell.Popup("Hi")

To retrieve a property from the same object, I use the dotted notation and access it directly. This is shown here.

$wshShell.CurrentDirectory

How do I call a function like a method?

The following code creates a simple function called test. It will write whatever I pass to it by using the Write-Host cmdlet.

function test {Param($a,$b) write-host $a $b}

When I call this function like a method, I use the parentheses next to the function call itself. This is shown here.

test("hi", "there")

If I want to enable strict mode, the previous command would fail. To enable strict mode, I use the Set-StrictMode cmdlet. This is shown here.

Set-StrictMode -Version 2.0

When I repeat the previous command, an error appears that states I attempted to call the function or command as if it were a method. This error message is shown in the image that follows.

Image of command output

There are two ways that I can type the command and avoid being “trapped” by strict mode. The first technique simply uses a space between each of the two parameters. The second technique uses named parameters. These two techniques are shown here.

PS C:\> test "hi" "there"

hi there

PS C:\> test -a "hi" -b "there"

hi there

PS C:\>

When I specify Set-StrictMode -Version 2.0, it checks the following items:

  • References uninitialized variables, both directly and from within
    strings
  • References to non-existent properties of an object
  • Calling a function like a method
  • Variables without a name

You may say, “But wait! Windows PowerShell 3.0 is coming around the corner. Do I need to go back and modify all my Windows PowerShell scripts?”

The answer is, “No.” I can set strict mode for version 1.0 right now on my computer running Windows 7 (with Windows PowerShell 2.0 installed). If I use strict mode for version 1.0, it only checks for references to uninitialized variables that are directly addressed; it does not check within strings.

If you always want to use the most stringent rules, set strict mode to Latest. In this way, Windows PowerShell uses the latest rules that apply to whichever Windows PowerShell version you are running. This could, however, cause scripts to break when unforeseen new rules suddenly apply.

Join me tomorrow for more Windows PowerShell cool stuff.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy 

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Do you add set-strictmode to each script?  Or is this cmd-let run once like enable-psremoting or set-executionpolicy?

  • @Tony you would need to add Set-Strictmode to each script. It goes away once the script runs (keeping in mind that it affects child scopes so if the script starts other scripts, or opens a powershell console it would be in effect there as well.