533

In a cmd prompt, you can run two commands on one line like so:

ipconfig /release & ipconfig /renew

When I run this command in PowerShell, I get:

Ampersand not allowed. The `&` operator is reserved for future use

Does PowerShell have an operator that allows me to quickly produce the equivalent of & in a cmd prompt?

Any method of running two commands in one line will do. I know that I can make a script, but I'm looking for something a little more off the cuff.

Peter Mortensen
  • 12,090
  • 23
  • 70
  • 90
David
  • 9,144
  • 3
  • 24
  • 41
  • 7
    Fun Note: Between Serial ports and Serialisation, this question is virtually impossible to search for. – David Jun 26 '13 at 17:25
  • 1
    To be nerdy... It's very easy to search for it. It's just quite hard to get a relevant set of hits. :) (+1 for great question) – Konrad Viltersten Jun 27 '14 at 16:01
  • 2
    Similar to [conditional execution (&& and ||) in powershell](https://stackoverflow.com/questions/2251622/conditional-execution-and-in-powershell). – JamesThomasMoon Dec 29 '18 at 22:30

5 Answers5

764

Use a semicolon to chain commands in PowerShell:

ipconfig /release; ipconfig /renew
Peter Mortensen
  • 12,090
  • 23
  • 70
  • 90
Squeezy
  • 9,232
  • 1
  • 16
  • 18
  • 18
    Will they run in parallel or sequentially? – Tarkus Jul 16 '14 at 01:13
  • 32
    This will run them sequentially, as does the & operator in cmd.exe. – Squeezy Jul 23 '14 at 05:38
  • 78
    There is big difference though - ";" runs the second command even if the first fails. – Ivan Oct 08 '14 at 16:50
  • 16
    As mentioned above, this is also the behavior of & in cmd.exe. – Squeezy Oct 08 '14 at 16:53
  • The second command won't run if the first throws a terminating error. In , "no error" is never written to the console. – Dave_J Jul 22 '15 at 10:59
  • 4
    There is a difference here in using the throw keyword ( throw being a keyword is the important part here ) directly and running a script that throws an error. will run both commands sequentially. This happens even though the first command throws a terminating error. – Squeezy Jul 22 '15 at 11:08
  • 8
    Is there a way to have the second command run only if the first fails? – Rafi Mar 22 '16 at 07:08
  • 11
    @Rafi Yes, Try {Command-One -ea Stop} Catch {Command-Two} – Dave_J Aug 05 '16 at 11:05
56

In PowerShell 7, we have Pipeline chain operators which allows you to add some conditional element to your sequential one-line commands

The operators are:

  • && this will run the second command only if the first one succeeds.
  • || this will run the second command only if the first one fails.

examples:

PS Z:\Powershell-Scripts> Write-Host "This will succeed" && Write-Host "So this will run too"
This will succeed
So this will run too

PS Z:\Powershell-Scripts> Write-Error "This is an error" && Write-Host "So this shouldn't run"
Write-Error "This is an error" && Write-Host "So this shouldn't run": This is an error

PS Z:\Powershell-Scripts> Write-Host "This will succeed" || Write-Host "This won't run"
This will succeed

PS Z:\Powershell-Scripts> Write-Error "This is an error" || Write-Host "That's why this runs"
Write-Error "This is an error" || Write-Host "That's why this runs": This is an error
That's why this runs

of course you can chain them even more together like x && y || z etc.

this also works for old cmd-like commands like ipconfig

PS Z:\Powershell-Scripts> ipconfig && Write-Error "abc" || ipconfig


Windows-IP-Konfiguration


Ethernet-Adapter Ethernet:

   Verbindungsspezifisches DNS-Suffix: xxx
   Verbindungslokale IPv6-Adresse  . : xxx
   IPv4-Adresse  . . . . . . . . . . : xxx
   Subnetzmaske  . . . . . . . . . . : 255.255.255.0
   Standardgateway . . . . . . . . . : xxx
ipconfig && Write-Error "abc" || ipconfig: abc

Windows-IP-Konfiguration


Ethernet-Adapter Ethernet:

   Verbindungsspezifisches DNS-Suffix: xxx
   Verbindungslokale IPv6-Adresse  . : xxx
   IPv4-Adresse  . . . . . . . . . . : xxx
   Subnetzmaske  . . . . . . . . . . : 255.255.255.0
   Standardgateway . . . . . . . . . : xxx

These operators use the $? and $LASTEXITCODE variables to determine if a pipeline failed. This allows you to use them with native commands and not just with cmdlets or functions.

Source: https://docs.microsoft.com/en-us/powershell/scripting/whats-new/what-s-new-in-powershell-70?view=powershell-7

SimonS
  • 8,924
  • 5
  • 28
  • 48
  • 1
    Not working. I tried in powershell: vagrant destroy -f && vagrant up. Does not work. – Basil A Apr 09 '20 at 11:05
  • 1
    @BasilA The documentation says: "These operators use the `$?` and `$LASTEXITCODE` variables to determine if a pipeline failed. This allows you to use them with native commands and not just with cmdlets or functions." so you should check if your non native commands set these correctly – SimonS Apr 09 '20 at 14:09
  • Okay, will check it up. Thanks. – Basil A Apr 09 '20 at 15:18
  • PowerShell 7!? why do these versions change so fast.. – austinheiman Jan 13 '21 at 18:32
  • 1
    Note that Powershell 5 is installed by default on Windows (even 11). Powershell 7 has to be installed separately. – pavon Jul 21 '22 at 23:42
37

A semicolon will link the commands as the previous answer stated, although there is a key difference to the behaviour with the & operator in the MS-DOS style command interpreter.

In the command interpreter, the variable substitution takes place when the line is read. This allows some neat possibilities such as swapping variables without an interim:

set a=1
set b=2
set a=%b% & set b=%a%
echo %a%
echo %b%

Would result in:

2
1

As far as I know, there is no way to replicate this behaviour in PowerShell. Some may argue that's a good thing.

There is in fact a way to do this in PowerShell:

$b, $a = $a, $b

It will result in a single line swapping of the variable values.

Dave_J
  • 481
  • 4
  • 6
13

For PowerShell 5 (default install for Windows machines for the foreseeable future), you can of course use a semicolon to separate statements, but all statements will be executed by default even if one fails. Personally, I prefer to run things so that if one thing fails the whole line stops in the REPL and I imagine a lot of other folks do as well.

$ErrorActionPreference lets you control the behavior of what happens when a statement fails but is a non-terminating error (which are most errors including command not found errors). You can set this variable $ErrorActionPreference="Stop" in order to emulate the behavior of && in Bash and PowerShell 7 for the scope of this variable.

$ErrorActionPreference="Stop"
# Line break
fakeCommand; echo "Here"

I have had trouble finding precise documentation for this behavior, but this variable seems to be dynamically scoped so you can override it in a block temporarily if you don't want to set it globally.

Invoke-Command -ScriptBlock {$ErrorActionPreference="Stop"; fakeCommand; echo "Here"}

Finally, if you want something reusable, you can use this higher order function.

function Run-Block-With-Error($block) {
    $ErrorActionPreference="Stop"
    Invoke-Command -ScriptBlock $block
}

Which is then used as follows.

Run-Block-With-Error {fakeCommand; echo "Here"}

Note in the examples above that "Here" is not printed since fakeCommand fails as it is not a real command.

I have tested the code provided in this solution for both PowerShell 5 and 7 and it should be fully portable, at least on Windows. While PowerShell 7 should be very similar on different platforms, I did not test these commands on Linux or MacOS.

Dyllon Gagnier
  • 133
  • 1
  • 4
0
"C:\\msys64\\mingw64\\bin\\g++.exe -g3 -Wall \"${file}\" -o \"${fileDirname}\\${fileBasenameNoExtension}.exe\" ; &\"${fileDirname}\\${fileBasenameNoExtension}.exe\""

In a powershell

Toto
  • 17,001
  • 56
  • 30
  • 41
  • 2
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community May 08 '22 at 14:50