Long PowerShell Commands (Backticks, gasp!)

Hrm… I know that the prevailing opinion in the community is that when you have a long command, avoid using the backtick character for line continuations in PowerShell. I know why authors avoid it, and I know the “gotcha” around having a space after your backtick causing weird stuff to happen. But dang it, this code:

    VisitCacheFiles -Source                     $SourceDirectory `
                    -Destination                $AgentDirectory `
                    -Exclude                    *.properties `
                    -OnMissingFile              ${function:TestAgentDirectory_OnMissingFile} `
                    -OnMissingDestinationFolder ${function:TestAgentDirectory_OnMissingDestinationFolder}

Is so much nicer to read than this:

    $splat = @{
        Source                     = $SourceDirectory
        Destination                = $AgentDirectory
        Exclude                    = '*.properties'
        OnMissingFile              = ${function:TestAgentDirectory_OnMissingFile}
        OnMissingDestinationFolder = ${function:TestAgentDirectory_OnMissingDestinationFolder}

    VisitCacheFiles @splat

Why? The first thing you see is the function name, instead of having some big hash table literal hitting your brain, forcing you to look down then back up again to see what’s going on. In fact, it’s easy to completely overlook the call to the actual function amidst all the other noise, when using splatting. Also, the vertical alignment of the parameters after the function name makes it very easy to see, at a glance, that they’re all associated with that command. (Or rather, that they _should_ be; no syntactic guarantees there.) I’m on the fence about whether to vertically align the arguments to those parameters as well, as I have in this post. It does seem to enhance the readability a bit more than when the parameters and arguments are a big blob of code.

So, I’m debating whether to start learning to love the backtick in my scripts. Before, I avoided it, but now that I’m using IseSteroids v2.0, I’ve noticed that it has two nice features related to line-ending backticks. First, it highlights them for you, making them easier to spot. The highlighting goes away if you have spaces after the backtick. Second, one of IseSteroids’ automated refactoring rules will detect backticks that are the last non-whitespace character on a line, and remove that offending whitespace. However, not everyone uses the same editor / addons, and when other people are reading or modifying my scripts, that could get annoying.

On a side note, Microsoft developers also appear to prefer the first style. You’ll see it all over the place if you look at things like the PSDesiredStateConfiguration and PowerShellGet modules. In fact, you’ll see relatively few uses of splatting at all in Microsoft’s modules, except where they’re either passing on an existing hashtable (e.g., @PSBoundParameters), or using splatting to dynamically create sets of parameters. (e.g., if ($Credential) { $splatParams[‘Credential’] = $Credential } )

What do you think? Is improved code flow / readability worth putting up with the possible gotchas around the tiny backtick? Does your choice of script editor affect that decision?


About Dave Wyatt

Microsoft MVP (PowerShell), IT professional.
This entry was posted in PowerShell and tagged , . Bookmark the permalink.

2 Responses to Long PowerShell Commands (Backticks, gasp!)

  1. anorhoads says:

    But why can’t I just
    VisitCacheFiles @{
    Source = $SourceDirectory
    Destination = $AgentDirectory
    Exclude = ‘*.properties’
    OnMissingFile = ${function:TestAgentDirectory_OnMissingFile}
    OnMissingDestinationFolder = ${function:TestAgentDirectory_OnMissingDestinationFolder}
    And not have the variable!
    But then I’d rather have the variable then the backticks 😉


    • Dave Wyatt says:

      With the syntax you’ve given, you’re just passing a hashtable as a positional argument to one parameter. There _has_ been some discussion about allowing us to splat literals, with something like @@{ Key = Value }, but I don’t know if it’ll become part of the language or not. (And even if it does, it won’t be backward compatible, so is not very useful to most script / module authors for quite some time.)

      Liked by 1 person

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s