633

Is it possible to split a PowerShell command line over multiple lines?

In Visual Basic I can use the underscore (_) to continue the command in the next line.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
eXXL
  • 6,548
  • 3
  • 19
  • 7
  • 4
    The "why not backslashes" question is covered nicely in Bruce Payette's _PowerShell in Action_; great book. Bruce has a broad knowledge of the history of programming languages. Looking forward to V2 of this book. – Jay Bazuzi Jul 15 '10 at 14:10
  • 4
    Duplicate of ... http://stackoverflow.com/questions/2608144/how-to-split-long-commands-over-multiple-lines-in-powershell – SteveC Nov 21 '13 at 15:40
  • 2
    Sorry if offtopic but if you are to submit the script with `sh` command, bash conventions hold so you can use backslash. In that case your script should also have unix style endings. – kon psych Mar 25 '16 at 04:02
  • just use ` character to separate command on multiple lines – Asad Shakeel Dec 17 '19 at 13:09

15 Answers15

886

You can use a space followed by the grave accent (backtick):

Get-ChildItem -Recurse `
  -Filter *.jpg `
  | Select LastWriteTime

However, this is only ever necessary in such cases as shown above. Usually you get automatic line continuation when a command cannot syntactically be complete at that point. This includes starting a new pipeline element:

Get-ChildItem |
  Select Name,Length

will work without problems since after the | the command cannot be complete since it's missing another pipeline element. Also opening curly braces or any other kind of parentheses will allow line continuation directly:

$x=1..5
$x[
  0,3
] | % {
  "Number: $_"
}

Similar to the | a comma will also work in some contexts:

1,
2

Keep in mind, though, similar to JavaScript's Automatic Semicolon Insertion, there are some things that are similarly broken because the line break occurs at a point where it is preceded by a valid statement:

return
  5

will not work.

Finally, strings (in all varieties) may also extend beyond a single line:

'Foo
bar'

They include the line breaks within the string, then.

Joey
  • 344,408
  • 85
  • 689
  • 683
  • You say "any other kind of parentheses will allow line continuation directly" but I needed the backtick for `$stream.WriteLine('foo'` *(newline here)* `+'bar')`. –  Dec 22 '14 at 16:39
  • 1
    @JackDouglas: You can have a line break directly *after* the opening parenthesis, but not within the expression before the operator, apparently. That being said, I believe that to be an oversight in the grammar. – Joey Dec 23 '14 at 08:07
  • Backtick does not work for me, the command never goes out of the multiline mode. – Didier A. Apr 03 '15 at 04:04
  • 12
    Line continuation doesn't work in the ISE command pane, apparently. – Khouri Giordano May 12 '15 at 16:05
  • This does not mean that if a cmdlet has further mandatory arguments, powershell will look on the next line for them. e.g. `new-aduser username` does not work. – Dan Pritts May 05 '16 at 02:04
  • @Dan: There's a difference between a cmdlet having mandatory parameters (which is a semantic thing) and the grammar telling you that the pipeline is incomplete (which is a syntax thing). The parser only knows how cmdlets and parameters look like, but not whether they are mandatory or not. Line continuation happens in the parser. – Joey May 05 '16 at 07:35
  • Makes sense - just wasn't how I imagined it working when I read the answer, so I wanted to point it out for the next person. – Dan Pritts May 05 '16 at 14:54
  • Just a note if you use a backtick to end a line, there cannot be any characters between the backtick and the newline, not even a space. Backtick escapes the next character, and if there's something between, then it won't escape the newline correctly. – Ryan Bemrose Aug 18 '16 at 23:17
  • @Ryan, as far as I know that's true in any language that has line continuation, so it didn't seem immigrant to mention it. – Joey Aug 19 '16 at 04:59
  • @Joey I only posted the comment because [this answer](https://stackoverflow.com/a/11828731) is up for deletion in review (it should have originally been a comment), but clearly it was important to at least 20 people. – Ryan Bemrose Aug 19 '16 at 17:45
  • Seems like the `\\` concat lines in shell. – coanor May 13 '20 at 02:43
111

There must not be any character between the backtick and the line break. Even whitespace will cause the command to not work.

Boris Verkhovskiy
  • 14,854
  • 11
  • 100
  • 103
Neffets
  • 1,183
  • 1
  • 8
  • 7
  • 15
    While this is technically not the answer to the question, +1 because this is absolutely essential. I just found this out the hard way, and will surely be avoiding the back-tick in future development wherever possible. – Dave Markle Nov 14 '14 at 17:51
  • 4
    So there is essentially no robust way to break a long line in Powershell. No wonder I tend to see those [2-screen-wide powershell scripts](http://stackoverflow.com/questions/2608144/how-to-split-long-commands-over-multiple-lines-in-powershell) every where. #ShakeMyHead – RayLuo Nov 21 '16 at 23:40
  • 2
    I was struggling with this, too... you can insert an inline comment before the back-tick to include a comment, like this: Some-Command ` -arg1 <# explain arg 1 #> ` -arg2 <# explain arg 2 #> – joelsand Sep 22 '17 at 18:09
  • 2
    Urgh. This makes PowerShell code unnecessarily difficult to post in documentation or websites, for fear that the command will either be read wrong by a human if using Shift+Enter, or parsed wrong in ISE's command line when using the back tick. – GuitarPicker Oct 26 '17 at 21:26
  • Down-vote due to the nature of the comment (which is not a complete answer to the original question). – CodeBreaker May 01 '20 at 15:36
  • 17
    **Technical Note** - this is because the backtick is *not* a line continuation operator per se; it's really an *escape* character that is serving to "escape" the newline at the end of the line. If you enter a space after the backtick, it'll escape that instead of the newline character. Further reading at [**Natural Line Continuations in PowerShell**](https://get-powershellblog.blogspot.com/2017/07/bye-bye-backtick-natural-line.html) – KyleMit Nov 06 '20 at 17:36
  • there's nothing strange in this. All C-like languages require the escape character to be immediately precede the new line without any whitespace in between. Of course that's because the escape is for escaping the new line and not the spaces – phuclv Dec 12 '20 at 06:32
  • Also, make your file's newlines Unix, not Windows, because Windows linebreaks are two characters, and thus the backtick will only escape half the linebreak. – Ariane May 31 '21 at 16:52
  • Hilarious but true! – Stephen Buck Aug 24 '23 at 15:08
44

In most C-like languages I am deliberate about placing my braces where I think they make the code easiest to read.

PowerShell's parser recognizes when a statement clearly isn't complete, and looks to the next line. For example, imagine a cmdlet that takes an optional script block parameter:

    Get-Foo { ............ }

if the script block is very long, you might want to write:

    Get-Foo
    {
        ...............
        ...............
        ...............
    }

But this won't work: the parser will see two statements. The first is Get-Foo and the second is a script block. Instead, I write:

    Get-Foo {
        ...............
        ...............
        ...............
    }

I could use the line-continuation character (`) but that makes for hard-to-read code, and invites bugs.

Because this case requires the open brace to be on the previous line, I follow that pattern everywhere:

    if (condition) {
        .....
    }

Note that if statements require a script block in the language grammar, so the parser will look on the next line for the script block, but for consistency, I keep the open brace on the same line.

Simlarly, in the case of long pipelines, I break after the pipe character (|):

    $project.Items | 
        ? { $_.Key -eq "ProjectFile" } | 
        % { $_.Value } | 
        % { $_.EvaluatedInclude } |
        % {
            .........
        }
Jay Bazuzi
  • 45,157
  • 15
  • 111
  • 168
  • how does `if` and `foreach` and `try` work then? they allow script blocks on the next line... this means it mut be possible – Nacht May 09 '12 at 01:52
  • @Nacht: From rusty memory: statements that require a script block, per the language grammar, will parse past a newline to find one. Can anyone confirm? – Jay Bazuzi May 09 '12 at 06:24
  • 2
    @Nacht: "But this won't work" was referring to situations where the further parameters are optional, which is most cases. – Jay Bazuzi May 10 '12 at 20:40
  • 1
    ah i see what you mean now. so "if" and "foreach" are not actually cmdlets - they are actuall part of the grammar, thus forcing it to look past to the next line. is there then no way to let a user-defined function read a script block from the next line? i suppose your above answer answers that question exactly. – Nacht May 14 '12 at 04:28
35

To expand on cristobalito's answer:

I assume you're talking about on the command-line - if it's in a script, then a new-line >acts as a command delimiter.

On the command line, use a semi-colon ';'

For example:

Sign a PowerShell script on the command-line. No line breaks.

powershell -Command "&{$cert=Get-ChildItem –Path cert:\CurrentUser\my -codeSigningCert ; Set-AuthenticodeSignature -filepath Z:\test.ps1 -Cert $cert}
Community
  • 1
  • 1
Alex
  • 359
  • 3
  • 2
  • 14
    Not the answer to the question, but your answer answered my question. :) – Frederik Feb 10 '12 at 18:24
  • 1
    That's interesting, but it's the opposite of what OP was asking. OP wanted to split a single command across several lines; you explained how to combine several commands onto one line. – Daniel Yankowsky Jul 28 '16 at 21:56
22

In PowerShell and PowerShell ISE, it is also possible to use Shift + Enter at the end of each line for multiline editing (instead of standard backtick `).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Bad
  • 4,967
  • 4
  • 34
  • 50
  • 2
    This is a great tip for editing multi-line here-strings, which are otherwise horrible to edit if you don't know the `SHIFT-ENTER` trick. – dpw Aug 31 '16 at 18:05
  • 1
    I believe this is the case in the console version of PowerShell only when using the `PSReadLine` module or an equivalent. In the standard Windows console input functions, `Enter` and `Shift+Enter` are functionally equivalent. – Bill_Stewart Jan 26 '17 at 18:39
  • @Bill_Stewart true, it works in the ISE console without PSReadline, but not in the Console Host. – briantist Jan 26 '17 at 19:41
  • 2
    To clarify: 1) The `PSReadline` module works in the console host _only_ (not ISE). 2) `Shift+Enter` works in the console host _only_ when using `PSReadline`. 3) `Shift+Enter` has always worked in the ISE. 4) If using the console host without `PSReadline`, `Shift+Enter` is functionally equivalent to pressing `Enter`. – Bill_Stewart Feb 08 '17 at 15:27
  • 2
    this is the right answer, the one which is accepted and have 400 up-vote is very confusing and useless!! – FLICKER Apr 11 '18 at 14:55
  • But how do I then execute? After I created a new line with shift+enter a normal Enter will only create another line with "<<" – Schnaps Apr 23 '21 at 07:27
13

Just add a corner case here. It might save you 5 minutes. If you use a chain of actions, you need to put "." at the end of line, leave a space followed by the "`" (backtick). I found this out the hard way.

$yourString = "HELLO world! POWERSHELL!". `
                  Replace("HELLO", "Hello"). `
                  Replace("POWERSHELL", "Powershell")
Jian Huang
  • 1,155
  • 7
  • 17
  • Thanks a lot! Tried to achieve this unsuccessfully for some time.. – tsul Aug 03 '20 at 03:45
  • Seems to work without space and backtick as long as you put the dot on the previous line, even if there are spaces after it and before the subsequent method call. Even comments work, like `Replace("HELLO", "Hello"). # comment here` – CodeManX Sep 17 '20 at 13:04
8

Just use ` character to separate command on multiline

Mariusz Jamro
  • 30,615
  • 24
  • 120
  • 162
Asad Shakeel
  • 1,949
  • 1
  • 23
  • 29
6

If you are trying to separate strings into multiple lines, you can use the "+". For example:

$header =    "Make," +

             "ComputerName," +

             "Model," +

             "Windows Version"

Will look just like:

$header = "Make,ComputerName,Model,Windows Version"
Nissa
  • 4,636
  • 8
  • 29
  • 37
4

I started by doing

if ($true) {
"you can write multiple lines here, and the command doesn't run untill you close the bracket"

"like this"
}

Recently found out I could just

&{
get-date
"more stuff"
}
JanRK
  • 147
  • 1
  • 5
4

This is an old post, so here's the modern method.

If you're not using legacy powershell, the cleanest way to continue lines is the pipe at the start of the line.

enter image description here

Note: The command doesn't break with some lines commented out. This is great on the command line.

> Get-ChildItem -path 'c:\' -Depth 1                 
    | Sort-Object LastWriteTime                       
    # | Sort-Object Length -Descending                   
    | Select-Object -First 3 -Skip 3                   
    | Foreach-Object {                                 
      $_.Name, $_.Length | Join-String -Separator ' = '                                                       
    }                                                  

output:

explorer.exe = 4826160                                 
procexp.old.exe = 2925760                              
RtlExUpd.dll = 2839488                                 

Windows Powershell ( Version < 6 )

Unfortunately windows powershell does not support it. A bunch of alternatives are linked above. You can remove the backtick completely: 2017/07/bye-bye-backtick-natural-line

ninMonkey
  • 7,211
  • 8
  • 37
  • 66
  • 2
    You're suggesting pipe, which is wrong answer. The correct answer is using **backtick `** followed by newline. – dns Sep 02 '22 at 08:00
  • Sorry for the confusion, maybe I was ambiguous there. using `backtick` to escape a newline is what I meant by legacy version. Because that's a limitation for `Windows Powershell` (`powershell.exe`) -- `Powershell` (`pwsh.exe`) added the pipe prefix as built in syntax. -- WinPs was end of life years ago, all development is on `Pwsh`. You can install them side-by-side. ---- If you're using `WinPS`, check out that link above. .[remove-the-backtick](https://get-powershellblog.blogspot.com/2017/07/bye-bye-backtick-natural-line.html) . You can almost entirely eliminate the need for backticks – ninMonkey Oct 03 '22 at 22:54
  • This only works if each new line is a new command. If it is multi-line, but each line is not a new command, then the pipe method does not work. Backtick is necessary there. – Brian Reading Jul 12 '23 at 00:46
3

I assume you're talking about on the command-line - if it's in a script, then a new-line acts as a command delimiter.

On the command line, use a semi-colon ';'

cristobalito
  • 4,192
  • 1
  • 29
  • 41
3
  1. Use a semi-colon ; to separate command
  2. Replace double backslash \\ on any backslashes \.
  3. Use "' for passing safe address to switch command like "'PATH'".

This ps1 command install locale pfx certificate.

powershell -Command "$pfxPassword = ConvertTo-SecureString -String "12345678" -Force -AsPlainText ; Import-PfxCertificate -FilePath "'C:\\Program Files\\VpnManagement\\resources\\assets\\cert\\localhost.pfx'" Cert:\\LocalMachine\\My -Password $pfxPassword ; Import-PfxCertificate -FilePath "'C:\\Program Files\\VpnManagement\\resources\\assets\\cert\\localhost.pfx'" Cert:\\LocalMachine\\Root -Password $pfxPassword"
Moslem Shahsavan
  • 1,211
  • 17
  • 19
2

There's sooo many ways to continue a line in powershell, with pipes, brackets, parentheses, operators, dots, even with a comma. Here's a blog about it: https://get-powershellblog.blogspot.com/2017/07/bye-bye-backtick-natural-line.html

You can continue right after statements like foreach and if as well.

js2010
  • 23,033
  • 6
  • 64
  • 66
  • 1
    A long but interesting article. Instead of escaping line breaks with backticks, one may use array splatting (even though the `@` splat operator doesn't seem to be necessary). For example: `$params = @( '-v', '-X', 'GET'); curl $params http://example.org`. Not `'-X GET'` but two separate elements are needed. And don't call the variable `$args`, it's reserved. – CodeManX Sep 17 '20 at 13:58
  • Or just a comma to continue. – js2010 Sep 17 '20 at 14:13
  • Yeah, no splatting is actually required, but quotes are: `curl '-v', '-X', 'GET', 'http://example.org'`. The recommendation from the article is to use a variable with splatting for readability however. BTW: If written on a single line and if you remove the spaces between the arguments, then it suddenly break? `curl '-v','-X','GET','http://example.org'` - `curl: option -v,-X,GET,http://example.org: is unknown`. A single space between any of the arguments makes it work again. – CodeManX Sep 18 '20 at 08:30
1
$scriptBlock = [Scriptblock]::Create(@'
  echo 'before'
  ipconfig /all
  echo 'after'
'@)

Invoke-Command -ComputerName AD01 -ScriptBlock $scriptBlock

source
don't use backquote

Mike
  • 20,010
  • 25
  • 97
  • 140
0

In windows terminal (powershell profile) I can simply click Shift-Enter works fine for me.

PS C:\xxx2021> Get-ChildItem -Include *remote* -Recurse |
>> Sort-Object -Property LastWriteTime -Descending  |
>> Select-Object LastWriteTime, Name -First 25

LastWriteTime        Name
-------------        ----
12/5/2021 5:04:02 PM remote-control-car-BatteryPack-Number-2021-12-03.pdf

PS C:\xxx2021>enter code here
Johannes
  • 3,002
  • 4
  • 33
  • 36
  • If it's not set by default, its the function `addLine` -> `Set-PSReadLineKeyHandler -Chord 'shift+enter' -Function AddLine` – ninMonkey Dec 24 '21 at 22:28