Great Debate: The Conclusion


All this Summer, we've been encouraging your feedback in a series of Great Debate posts. Most of the topics came from the 2013 Scripting Games, where we definitely saw people coming down on both sides of these topics. My goal was to pull everyone's thoughts together into a kind of community consensus, and to offer a living book of community-accepted practices for PowerShell. This'll be a neverending story, likely adapting and growing to include more topics as the years wind on.
But here's the start: DRAFT-2013Sep_Practices is the first draft, officially a Request For Comments, based on the comments you've all contributed to the Great Debate posts over these past few weeks. I tried to capture consensus where I saw it, and to outline both sides of the great back-and-forth we've seen.
NOTE: The cover image in this draft is just a placeholder; this book is NOT dedicated to error handling. Its working title is correctly shown on the page following the cover image.
I'm going to leave this post in place until October 1st. Please drop any comments you'd like to offer to the final first edition of this ebook, and let me know if there are any topics you'd like to see debated in the future. After October 1st, I'll publish the final edition of this Practices guide as one of's free ebooks. The final first edition will also become part of the next iteration of The Scripting Games, as its official "best practices" guide. In fact, you'll notice in this draft that there are a couple of Games-specific comments, since the Games sometimes have different drivers than a production environment.
Thanks again to everyone who participated!

9 Responses to " Great Debate: The Conclusion "

  1. Dave Wyatt says:

    I don’t care for the conclusion of “Pipelines vs. Constructs.” There are times when using a pipeline is the only correct answer, regardless of what you prefer aesthetically. The code in the draft is a perfect example:

    $computers = Get-Content computer-names.txt

    The script has no idea how large the computer-names.txt file is, but this statement forces you to load the entire contents of the file into memory. In PowerShell Deep Dives, this is referred to as a “water balloon”; try to put too much into it, and it’s going to pop (chapter 15, Scalable scripting for large data sets: pipeline and database techniques).
    Piping the Get-Content cmdlet to ForEach-Object, on the other hand, streams lines of the file one at a time, without having to ever store the entire thing in memory.

    • Don Jones says:

      From both an aesthetic and performance perspective, I wouldn’t use Get-Content at all in that situation.
      But, my conclusion was based on the aggregate comments to that particular debate post. It wasn’t my opinion – it was the opinion of a larger group of people. It was not the only opinion, and I tried to be extremely clear in the outset of the piece that thee would ALWAYS be situations where the prevailing opinion wasn’t appropriate, because the prevailing opinion is somewhat generic and lacks context. I don’t think it’s reasonable to cover every single possible scenario where the prevailing opinion might have exceptions. I really did try to wrap “performance sometimes overrides preference” throughout the various conversations.

  2. Matt Penny says:

    First off, thanks for doing this. It’s a good idea and will be a very valuable thing for lots of people.
    Second, a minor suggestion – it might be worth thinking about heading and labeling each individual ‘best practice’.
    I’ve got a copy of a book called ”Oracle PL/SQL Best Practices” by Steven Feuerstein, and he does it in quite a neat way. The book has a quick reference which summarizes each of the 145 or so ‘best practices’ in 1 or 2 sentences. The rest of the book has a section explaining and justifying the best practice in more detail. For Powershell, it might be a one page quick reference and a few pages of explanation.
    Anyway, the ‘best practice’ is given a label, for example:

    STYL-04: Tag module END statements with module names

    You can then say ‘our project aims to follow Feuerstein’s best practices except for STYL-04, SQL-03 because blah blah blah
    Also, it might aid further discussion here a little bit?
    Also, I quite like the clarity it brings. For example:

    COMM-01: Include comment-based help in your scripts and functions. Your help should be
    helpful. That is, if you

    • Don Jones says:

      If I were creating a book that would sell and help pay my mortgage (as Feuerstein did), I’d totally take the time to do all that (grin). As a volunteer effort, I can only invest so much time before the utility companies start knocking on the door and asking for their money… but if you’re volunteering to curate the book and do all that, contact me at

  3. Hi Don!
    I realy love that you doing tha (for free). I thing the booklet name “Error Handling” is totally missleading. I think it is a bit hard to classify performance and aestetics as Errors.
    The sub title “best practices” is more applicable. But If you read the book with this Tilte written by Ed Wilson, the you see the tile is burned (will not roast the book here).
    I am an .NET developer and a Sysadmin (a real DevOp ;-)) So I was reading many .NET books. One of my favorite in love is the “Framework Design Guidelines” book.
    This Book defines, even for PowerShell, many best practice rules!
    I even loved to read the comments and advices from the scripting games judges.
    Even Aman Dhally is doing a Blog series right know about best practices.
    Perhapst you can collect and concentrad this work. You are concentrated Don!
    I suggest the Title “PowerShell design guidelines from the community” or so.
    I think the best thing we can do with such topics is to start a open wiki! So the community stuff stays in community and is not owned and named by one Person.
    You have to give credits to the originator. The originators are not named.
    I like the TechNet Wiki because the originator is visible for all peoples and the community can contribute. Even the gamification aspect is there to earn points and honor are very important.
    I think gamification and earning something to grow in the community is essential for a good community portal.(nobody can beat you ;-))
    I have searched very long for a community platform with this requirements. I found: Sharepoint 2012 is good for that or Dotnetnuke or Liveray. But this is another topic…..
    Sorry for my bad english this took me 1 hour to write ;-))
    grrets Peter!

  4. Mike Shepard says:

    First of all, let me say that I think you’re doing the PowerShell community a great service by creating this document (especially given the Scripting Games and Great Debate that have lead to it).
    Here are a few things I found when reading through it.
    1. The title graphic still says “PowerShell Error Handling”
    2. On page 8, the first sentence in the second paragraph says “is useful or anyone” but should probably say “is useful for anyone”.
    3. On constructs vs. pipelines, I agree in general that constructs are almost always better in terms of readability and performance, but I also agree with Dave Wyatt above that using them with a large file (and get-content) will lead to significant issues. I just re-read the comments on the original article and I think (in retrospect, I didn’t see it this way at the time) that Dave Wyatt’s reply there is good advice: If you have the collection in memory already, use foreach, otherwise, it might be best to use foreach-object.
    4. In terms of backticks, the place I see them the most is in books, where constraints in typesetting force some usually avoided line-breaks. Don’t know if that warrants a mention, but it’s something I thought of while reading.
    5. I don’t usually use [void] as shown in “The PowerShell Way”, so had to pop into ISE to do some looking. It seems that statements like [void]get-service don’t even parse (I’m running v4.0). To get it to run, I needed parens around the cmdlet, which makes it even less attractive.
    6. The last thing I thought of is that while this is a great summary of “controversial” best practices, it would be much more useful for new scripters or people trying to get their codebase up-to-snuff would be to include a list of the “non-controversial” best practices, like the list that you have at the end of PowerShell In Depth (chapter 40).

  5. Jon Newman says:

    Trapping and Capturing Error correctly discusses “$_” as the way to get the error which occurred, but doesn’t discuss how to examine “$_” within the catch block to determine which error occurred. IMO it is common for a catch block, or error handling block generally (if you’re just using ErrorVariable and not throwing), to be specific to a particular error. Here are a couple ways to dissect errors:
    (1) Check the type of the exception, either by specifying it in the “catch” line, or by using “[is]”. Sometimes you have to look one or two steps down the InnerException chain.
    (2) Use ErrorRecord.FullyQualifiedErrorId. This is usually pretty specific to the error, sometimes even more so than the exception type. Which technique works better will depend on the cmdlet you are calling and how it was written.

    • Don Jones says:

      I think the guide is more about “what” to do than “how.” It isn’t intended to be an instructional guide, but rather a description of accepted practices. While that information on how-to-see-the-error is obviously 100% useful, it goes (for me) a bit beyond “practices.” Keep in mind that this is a volunteer effort – putting together a solid how-to is more time than I can personally invest right now, and still get my paying work done. That said, if someone would like to volunteer to write up what you’re talking about, with appropriate examples, I’d be happy to include it (along with credit where due). Just contact me. (As an aside, the cover image in the draft book was a placeholder – this book isn’t intended to be error handling; that’s another project)