Learn about Windows PowerShell
Summary: Microsoft Scripting Guy, Ed Wilson, shares what he noticed while grading the 2014 Winter PowerShell Scripting Games entries.
Microsoft Scripting Guy, Ed Wilson, is here. So the 2014 Winter PowerShell Scripting Games are over. One of the cool things about this year’s Winter Games is that they were team events. This means that groups formed and tackled some pretty difficult scenarios as a team. This also means that the quality of the submissions was extremely high. I thought it would be interesting to go over some of the things I noticed while grading the submissions this year.
I have written quite a bit about aliases in scripts. Here are some of the posts related to aliases:
Don’t get me wrong, Windows PowerShell aliases are extremely useful, and they make working interactively from the Windows PowerShell console fast. The thing is that this fast aspect tends to be a tradeoff for readability.
When using the Windows PowerShell ISE and when writing a script, Tab expansion and IntelliSense offer improvements that can make quick work out of the task of typing extremely long cmdlet names. In fact, this tool of Tab expansion and IntelliSense is one of the reasons that we can have long, descriptive cmdlet names.
It is a strength of Windows PowerShell that I can read the script and pretty much understand what it is doing—even if I am unfamiliar with the module or the technology. For example, someone someday may write a cmdlet named Invoke-VirusScan. Without having seen the cmdlet or having read any help, I can imagine that the cmdlet will kick off a virus scan.
I would also imagine that there should be parameters for which disk to scan, or an –all switched parameter, and even a –skip parameter so that I can choose to not scan certain file types and folders. But, on the other hand, if I see an alias called ivs, I have no idea what the command does.
There are many aliases that look like other things, for example: Kill, Dir, Where, and Sort. For example, Sort is also the name of an executable in CMD. This is shown in the image that follows:
When the cmdlet , Sort-Object, does not behave like Sort.exe, the person attempting to write the script becomes confused and wonders why it does not work. This is also true of Dir, Kill, and others. The fact that I can start CMD inside of Windows PowerShell, as shown in the previous image, means a whole lot of confusion.
In fact, one alias, Foreach for the Foreach-Object cmdlet is also the name of a Windows PowerShell keyword, Foreach. These two identical looking commands behave completely differently, and this causes a serious stumbling block for beginners—and even for some intermediate scripters.
So, the best thing to do in a script is to avoid using aliases. It is easy enough to do. You can use my Remove-AliasFromScript function that is part of my Windows PowerShell ISE profile and modules, or you can simply use Tab expansion to complete the cmdlet names. The advantage is that not only do you get ease of entry, but you also get correct spelling and cases.
At the beginning of the chapter on debugging in my book, Windows PowerShell Best Practices, I mention that if you can read and understand your script, you will eliminate nearly 90 percent of all mistakes that eventually lead to a debugging situation. I am firmly convinced that this statement is true. You can also contribute to that percentage by developing good, sound development techniques.
One of the things that contributes to reading Windows PowerShell script is how it is formatted. There are two extremes that should be avoided:
When working interactively at the Windows PowerShell console, I love one-liners. Those pithy one-line commands that seem to accomplish great things. The fact that it may wrap for several lines inside the Windows PowerShell console does not deter usefulness, but it does impair reusability and debugging in the event that the one-liner does not work. But, hey, that is the Windows PowerShell console.
I really avoid this inside the Windows PowerShell ISE. The Windows PowerShell ISE can be used to run interactive commands, but I like to use it as a way to break down the script and make it easier to read—even if it is a logical one-line command.
Following is an example of what I am talking about. When I run the script that is shown in image of the Windows PowerShell ISE, nothing happens. No error generates, nothing appears.
I have to scroll over to look at the remainder of the command. But when I do that, I still cannot see the entire command, so it makes troubleshooting a major pain. Here is the scrolled over portion of the script:
It is obvious now why nothing appears to happen. I am starting a process, then getting the process, and then stopping the process—all in the same one-liner.
One of the best ways to fix this issue is to separate the script at the pipeline character and at the semicolon. In fact, I do not even need the semicolon now that I have things broken out onto individual lines.
The opposite extreme is too much tabbing. It results in exactly the same type of situation. The script becomes hard to read, as shown in the following image:
The solution, once again, is to tighten up the script. It is OK to indent and to align, but not if it comes at the expense of readability. Instead of using a full tab, I often only use a single or at times a double space for my indentions. I find that it makes my script easier to read, and therefore, easier to debug if it ever comes to that.
2014 Winter Scripting Games Wrap-Up Week will continue tomorrow.
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