Summary: Ed Wilson, Microsoft Scripting Guy, talks about debugging Windows PowerShell scripts.
Microsoft Scripting Guy, Ed Wilson, is here. One of the cool things about central Florida is there are lots of farmers markets… especially (I am told) this time of the year. This is great, because I prefer organically grown, locally sourced food. I mean, I like my food to be simply food—not food and a whole lot of additives and other things. My simple rule is this: If I cannot read and pronounce it, then I won’t eat it. Although I have taken many science classes at the university, I have not had a chemistry class—so maybe that is part of my problem. Don’t know.
I need to read and understand my script
Scripting, for me, is a lot like my tastes in food. If I can read and understand my script, I am happy. If not, I try to do something about that. As a result, I seldom need to use the debugger on my own scripts. But from time-to-time, I get roped into someone else’s script project or I get sucked in to troubleshooting someone’s script. For whatever reason, I am confronted with code that I didn’t write. So all this week, I am talking about debugging Windows PowerShell scripts.
Often my first step is to simply reformat
I am not talking about reformatting my hard disk drive, although that is often helpful. No. Quite often if I cannot read someone’s script, I will start by reformatting the code so that it at least looks more like a Max Klinger than a Pablo Picasso.
I like to indent subordinate clauses and not indent major statements that are not dependent on anything else. So it is sort of like an outline. I start with a major heading, and then I indent things that are subordinate to the major heading. When I come back to things that are not subordinate, I go back to the unindented lines.
I like to group things together. For example, I like to have variable assignments and constants at the beginning of a script if they are part of setting up the environment for running the script. Obviously, if they are locally scoped to a function, the variables are in the function itself.
I like to initialize variables, even to $null, if they are used as counters or otherwise dependent on running of the script. In this way, I do not have to rely on the variables being created and initialized because they could pick up something that may be left over. This is especially important when using the Windows PowerShell ISE, and running a script multiple times or when leaving the Windows PowerShell console open for long periods of time and doing a lot of interactive stuff.
If simple formatting does not do the trick, I begin to reach into my bag of tricks. For example, I may use Write-Debug and print debug statements that tell me what variable values are at different parts of the script. I will also print statements about making connections to a remote server, attempting authentication, and other aspects of the script as it runs.
If that doesn’t work, I will probably use the Set-PSDebug cmdlet and set a trace level of 1 or 2 to see how the script is running, to get an idea of the flow, and to see if I can catch any errors that arise from the flow of the script.
Depending on what happened with Set-PSDebug, I may turn on strict mode. To do this, I use the Set-StrictMode cmdlet and specify either version 1 or version 2. Version 1 is useful for finding problems with variable assignments and values, and version 2 is helpful in picking up some scripting best practices (such as calling a function like a method).
And if that doesn't work…
I will break out the debugger. To be honest, I like using the debugger in the Windows PowerShell console. For me, it is easy and intuitive, and it works very fast. But I can do the same thing in the Windows PowerShell ISE.
The easiest thing in the world is to set a breakpoint on line one for the script, run the script—and Bim! Bam! Boom! I am in the Windows PowerShell debugger. I can then do things such as step through the script line-by-line, look at code blocks, and change variable assignments. It’s a very powerful tool, and it is best to learn how to use before tackling serious problems.
Debugging Week will continue tomorrow, so come back when I will begin by talking a bit about using the Write-Debug cmdlet.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at firstname.lastname@example.org, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy