Don't Use PowerShell One-Liners (In Some Cases)

February 14, 2015 by Christopher Walker

And other PowerShell no-nos in my book

“They” say that our biggest critic is ourselves and this applies to all crafts that we partake in; to include scripting, programming, and administering technology. I am typically highly critical of my own work and I scrutinize till I believe it is perfect (more so when I know others will read it). I also carry over that intense scrutiny when I critique other’s work. When it comes to writing PowerShell, I can be on the edge of annoying. Knowing this, I’d like to share some of my grievances when it comes to reviewing PowerShell automation scripts.

These pet peeves do not apply to console scripting. If, for example, I quickly jump into my Hyper-V server to grab some information about the VMs that are running, I will break some of these rules since I will be in and out of the server after I gather my information or make whatever miniscule change. This would be console scripting. Now, if I am going to reuse this script for automation purposes in the future (an automation script), I will typically follow these rules to a “T”.

We will see how much content this generates but I may have to make this a series. I want to start off in this post with one of my biggest irritations when reading PowerShell scripts; (as the title reflects) one-liners.

I love the | character. I think it is one of the best things about PowerShell. Clearly the pipe has been used in many other scripting languages but PowerShell implements it quite successfully. The pipe gives us the ability to create one-liners, which are great when you are console scripting because let’s face it, multi-line commands in the shell doesn’t look pretty at all.

However, if you are going to write a script that you intend on keeping/sharing, I recommend staying completely clear of those massive one-liners you may see in the shell. A written script should have the same formatting and readability as any other code. This includes indenting, competent variable declaration and naming (more on that later), proper commenting (more on that later too), and generally following the encouraged PowerShell coding conventions.

Generally, continuing down the pipeline on the same line of code is hideous looking, making the code unreadable. When code is unreadable it makes it hard for either you or someone else on your team to come back and decipher what the code snippet is being used for. This makes it especially difficult if this one code snippet is in a massive script full of other one-liners.

For example, a person looking up the average uptime of all their currently running VMs in Hyper-V may execute a one-liner in the shell like this:

(Get-VM | ?{$_.State -eq "Running"} | Select -ExpandProperty Uptime | Measure-Object -Average -Property TotalHours).Average

That’s a tad unreadable. Granted, I can tell what the outcome of this line is, but it take me longer to figure out what it does than if it were cleaned up a bit. If you were going to save this and use it for later, I recommend one of two options.

$RunningVMs = Get-VM | Where-Object -FilterScript {$_.State -eq "Running"}
$Uptime = $RunningVMs | Select-Object -ExpandProperty Uptime
$Average = ($Uptime | Measure-Object -Average -Property TotalHours).Average

Perhaps this is just personal preference (and this probably isn’t the best example) but I like to think it looks cleaner. The second version only uses one pipe per line and assigns variables for each of the values in between steps. If you don’t like assigning all those values, at least break up that one-liner into several lines. The cool thing about the pipe is that it doesn’t care about whitespace, including new lines/returns, to the right of the character. You can break up that one-liner up to look like this.

$Average = (Get-VM | ?{$_.State -eq "Running"} | 
            Select -ExpandProperty Uptime      | 
            Measure-Object -Average -Property TotalHours).Average

This is still readable, still valid, and it looks great. My example one-liner is about the best I could come up with while writing this article. I have seen others out there in the wild, fused into scripts and baffling everyone that came across them. I have seen the -PipelineVariable parameter abused too many times to count. Perhaps this is just me being anal-retentive, but I like reading readable scripts.

I think I’ve gotten the main point across about one-liners. I think I will continue this as a little series on my personal dislikes about PowerShell code that I have seen. Check regularly for new blogs on the site.

Privacy Policy

© 2017 | Powered by Hugo and lots of motivation.