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:
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
So simple and so significant `
Thanks