Weekend Scripter: Don’t Break PowerShell Script with Line Breaks


Summary: Microsoft Scripting Guy, Ed Wilson, talks about line breaks in Windows PowerShell.

Microsoft Scripting Guy, Ed Wilson, is here. This morning, the weather is cool for a change. It was a great morning to get up and take a walk through a peach grove. There is actually a sidewalk through the peach grove here. Peach season is nearly over, so the peach trees still have leaves, but no peaches on them now.

One of the problems with writing books, blogs, and papers about Windows PowerShell is that the line length is pretty much limited to 80 characters. With modern monitors and the Windows PowerShell ISE, I can have lines that are nearly triple that length. The line still fits on screen, and I do not have to scroll.

There is, in fact, a double-edged sword with Windows PowerShell. The commands are easy to read and understand, but quite often, cmdlet names are incredibly long. The argument is, "Well, with Tab completion, I do not actually have to type the complete cmdlet name."

But the argument contrary to that is, "With thousands of cmdlets, Tab completion is not as effective as it once was." In fact, on my laptop, there 13 cmdlets that have names that are 41 characters long or longer. Here is the script I wrote to figure this out:

PS C:\> Get-Command | select name, @{LABEL='length';EXPRESSION={($_.name.tostring().length)}} |  sort length -Descending | where length -ge 41

Name                                                                               Length

—-                                                                               ——

Disable-NetAdapterEncapsulatedPacketTaskO…                                           47

Enable-NetAdapterEncapsulatedPacketTaskOf…                                           46

Set-WinAcceptLanguageFromLanguageListOptOut                                            43

Remove-VMNetworkAdapterRoutingDomainMapping                                            43

Remove-VpnConnectionTriggerDnsConfiguration                                            43

Get-WinAcceptLanguageFromLanguageListOptOut                                            43

Get-NetAdapterEncapsulatedPacketTaskOffload                                            43

Set-NetAdapterEncapsulatedPacketTaskOffload                                            43

Get-VMNetworkAdapterFailoverConfiguration                                              41

Remove-VpnConnectionTriggerTrustedNetwork                                              41

Reset-MsolStrongAuthenticationMethodByUpn                                              41

Set-VMNetworkAdapterFailoverConfiguration                                              41

Reset-MsolStrongAuthenticationMethodByUpn                                              41

When I have a cmdlet that is 47 characters long, I have little hope of fitting the command on a single line. So what do I do?

Pipe to the left

The easiest thing to do with a Windows PowerShell script is to break the line at the pipe character, and then continue the script on the next line. In the following examples, I am using the Windows PowerShell ISE with Windows PowerShell 4.0 on my Windows 8.1 laptop.

Note  If I am typing interactively at the Windows PowerShell console, I can keep typing and the command will wrap and go to the next line. The problem comes when I try to paste that command into a Word document or into a blog. It confuses people, and often when they try to copy and paste from the blog to the Windows PowerShell ISE, the script simply does not work. This can be really frustrating. One solution is to upload the script to the Script Center Repository and simply let people download it. This is what I do for longer scripts.

Breaking the script at the pipe character often works well. It is my preferred way of doing things. Here is what my previous script works out to be:

Get-Command |

select name, @{LABEL='length';EXPRESSION={($_.name.tostring().length)}} | 

sort length -Descending |

where length -ge 41

Break at commas to create incomplete commands

Another easy way to break the script is to break it at the comma. When I do that, Windows PowerShell realizes that there will be more to the command, and it automatically looks to the next line. So again using my previous script as an example, I can break at the comma between Name and my new property, Length:

Get-Command |

select name,

@{LABEL='length';EXPRESSION={($_.name.tostring().length)}} | 

sort length -Descending |

where length -ge 41

Break at a semicolon

Using the same principle as the comma, I can also break my command at a semicolon. I can even indent a bit, to line things up and make it easier to read. This is shown here:

Get-Command |

select name,

  @{LABEL='length';

       EXPRESSION={($_.name.tostring().length)}} | 

sort length -Descending |

where length -ge 41

Break at the equals sign

I can also break the script at the equals sign. So as shown here, at Expression =, I break the command at the equals sign:

Get-Command |

select name,

  @{LABEL='length';

       EXPRESSION=

         {($_.name.tostring().length)}} | 

sort length -Descending |

where length -ge 41

When it doesn't work…

There are times, however, when it just doesn't seem to work out the way I would like it to. For example, when I use the following script, an error message appears that says –unique is not a recognizable command.

Get-Process -Name notepad -ComputerName $env:COMPUTERNAME |

    Select-Object -Property processname, id,

        handles | Sort-Object -Property processname -Descending

        -unique

What if I leave the hyphen ( ) on the upper line, and hope Windows PowerShell is smart enough to continue to the next line?

Nope. The following command also generates an error message:

Get-Process -Name notepad -ComputerName $env:COMPUTERNAME |

    Select-Object -Property processname, id,

        handles | Sort-Object -Property processname -Descending –

        unique

This is where I use line continuation

For those occasions where I cannot break a command logically so that Windows PowerShell realizes I want to go to the next line to complete the command, I have to use the line continuation character. The line continuation character is the backtick ( ` ). (This is also known as the "grave accent." On my keyboard, it appears under the tilde ( ~ ).)

The revised script is shown here:

Get-Process -Name notepad -ComputerName $env:COMPUTERNAME |

    Select-Object -Property processname, id,

        handles | Sort-Object -Property processname -Descending `

        -unique

Here is the command and output from the command as seen in my Windows PowerShell ISE:

Image of command output

Join me tomorrow when I begin a discussion of WMI and Windows PowerShell.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

Comments (5)

  1. Keith Garner says:

    Some additional notes:

    about_Escape_Characters – I take exception to the PowerShell documentation calling the backtick character "Line Continuation". When you place it at the end of the line it *escapes* the new line, fooling the parser into thinking it’s the same line. If you have
    any whitespace after the tick, the parser won’t escape the newline character. This is somewhat dangerous for scripts, and a hack to begin with.

    about_spatting – One of my favorite ways to make PowerShell scripts more readable is to use Splatting. This works best when you have cmdlets that take long parameters. Put all your parameters in a hash table:

    $SortParams = @{
    Property = "processName"
    Descending = $True
    Unique = $True
    }
    Get-Process -Name notepad -ComputerName $env:COMPUTERNAME |
    Select-Object -Property processName, id, handles |
    Sort-Object @SortParams

    About_Parsing – Also, there is no need to add a semi-colon at the end of a line to make a break, since the semi-colon is a "Command Delimiter" along with newline.

    Thanks for the post Ed!

  2. Sam Boutros says:

    I like them all except the backtick ( ` )… it’s confusing and can be missed when reading a script..

  3. xajuan Smith says:

    This may sound surprisingly odd. What key(s) are you typing to break the line or are you typing enter to get ">>"

  4. Chris S says:

    "Grave accent"?

    More like lower-case tilde.

  5. Sam Chang says:

    Is the backtick specific to the PS ISE? The backtick doesn’t appear to work in the context of the PS command line.

Skip to main content