During the most recent PowerShell Scripting Games, I was fortunate enough to be one of the judges. Now that the games have concluded I thought I'd share my reflections on the entries. Naturally these are merely my opinions but they are drawn from years of experience with PowerShell and almost 25 years as an IT Pro. All I can hope is that you'll consider some of these things on your next PowerShell development project.
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
Let me also be clear, for those of you still new to PowerShell, that when using it interactively at a PowerShell prompt, anything goes if it helps you get the job done efficiently. But when you are creating a scripted PowerShell solution, something that will live on, then the guidelines are a little different.
It is true that the challenges for this past set of games were complex. Frankly, I'm not sure how I would have even started on a few of them. That said, we're still talking about PowerShell scripts in the end. One thing that struck me on the entries I judged, was how often I felt I was reading source code for a Visual Studio project and not a PowerShell script. On one hand that could be considered a good thing: PowerShell is flexible enough to create anything from basic scripts to the types of entries I reviewed. But then again, if you have the technical chops to come up with code like I read, you probably could create a "real" set of compiled tools. At some point in your development process you might ask yourself if you are creating a PowerShell script or have moved beyond and maybe a script isn't the right solution. Yes, the game entries needed to be PowerShell scripts and modules but what about what you're working on?
Even so, this brings me to my next point: maintainability. The best way to test this is to hand your script files to someone else, ideally with a little less PowerShell knowledge than you, and see if they can understand what your scripts do and how. Many of the entries I read were sprawling, complicated masses of functions and scripts and .NET code. I was challenged in many cases to try and figure out what was going on. If *I* have to struggle to figure out how all the pieces of your script or module work, think about your co-worker who gets handed your solution to maintain or troubleshoot when you get promoted. Or it might be you coming back to it in 6 months.
There is no penalty for comments. I encourage beginners to write the comments first so that they can organize and plan their work. For a module, you can also write your own About help topics. In my opinion, information like this is just as important as the PowerShell commands you are using.
Lastly, I have the usual concerns about syntax and language choices. Yes, I know there are always exceptions. Don't resort to using .NET classes when a cmdlet will do. Use standard verbs and meaningful nouns in your command names. But perhaps the biggest peeve for me is the continued use of the Return keyword.
Whenever I see the Return keyword, I feel the script author has not fully grasped the PowerShell paradigm. To my way of thinking we don't return values we write objects to the pipeline. The only time I use Return is when I intentionally want to bail out of a script or function and gracefully terminate everything. Usually when I see the use of Return I also see a lot of unnecessary helper functions each intended to "return" something. This only adds to the (unneccessary) complexity of your work. Add in a lack of documentation and you have a mess of, let's call it, sub-optimal PowerShell.
A well-crafted PowerShell script file can be a thing of beauty.
The pipeline opens,
objects blossom sending joy
formatted as bliss
What do you think? What have you seen in your company or in the wild that is good, bad or ugly?
I don’t have a strong opinion on the rest of it, i’m still overwhelmed by the Powershell Haiku…
I thought it was a good article but I’m unclear as to what you were saying in the first half. Were you saying that for writing tools like we made in the games we should be looking more at C# than PowerShell?
The games require PowerShell scripts. What I was trying to say in the beginning that in the “real world” at some point you might need to assess what you are working on and decide if a PowerShell script is the right tool or if you would be better serve by writing a C# project. That said, if an entry for a Scripting Game event is complicated enough that you are writing what amounts to C# source code, then you absolutely should address my other concerns regarding maintainability. Don’t write PowerShell scripts for yourself. Write them for the next person.
I tend to use the return keyword in helper functions that are intended to only ever return a single value, and Write-Output in “Cmdlet”-style advanced functions that are intended to be used in a pipeline. This basically mirrors how Cmdlets are written in C#; there are lots of functions that return values, but the Cmdlets themselves eventually call Cmdlet.WriteObject() to pass things down the caller’s pipeline.
I don’t feel that these helper functions are unnecessary. When I use them, they’re there for a reason: either to eliminate duplicate code, or to make the calling function more readable by collapsing a large block of code into a single function call with a descriptive name. Either way, it should contribute to making the script easier to read and understand.
Thank you for taking the time to comment.
A big problem from my perspective was that many of the entries were not easy to read or understand. I think IT Pros also need to be careful with these “helper” functions. For example, a function to “return” the operating system and another to “return” the service pack is poor Powershell planning from my perspective. Instead write a function that returns an object with the information you need. Sure, I get that there are times where a function can be used for a single value but I think you should ask yourself if that is the best approach in the big picture. And for the real-world, I’ll stick with my assertion that at some point you need to ask yourself if your solution should be a PowerShell script or a C# project. Just because you can write it in PowerShell doesn’t mean you should.
Well that’s an interesting perspective regardless. I’ll have to look deeper into C#. I definitely took the approach that if I know PowerShell I should just write it in PowerShell. I guess part of my problem is I don’t understand C# well enough to know why I would want to use it.
I’m speaking generally, but there’s “write it in PowerShell” and then there’s “write PowerShell”. I’ve seen a lot of examples where all that was done was take a VBScript approach (or even C#-ish ) and wrote it in PowerShell. That doesn’t necessarily make it good PowerShell. I guess what I’m getting at is that not only is there a technical approach to PowerShell one needs to master but also a philosophical as well.