Pasting multiple commands in PowerShell pauses execution after cmd.exe

BW 0 Reputation points
2023-08-14T19:31:25.5+00:00

My typical experience with PowerShell is I can copy/paste multiple lines of commands to execute, and PowerShell executes them in sequence without interruption.

For example, I can copy these 5 lines and paste them in PowerShell:

Write-Host "=== START TEST ==="
cmd.exe
ping localhost -n 1
exit
Write-Host "=== END TEST ==="

And PowerShell will dutifully execute each command at each prompt:

User's image

But I've recently encountered some environments where execution "halts" after cmd.exe, and only continues once I've manually exited the command prompt:

User's image

Is this a behavior I have control over? How to I make the second environment behave like the first one?

NOTE: I know there's other ways to make my example work without copy/pasting the commands as I've shown. I'm not interested in alternatives to this specific use case. I am interested in achieving consistent behavior when copy/pasting commands like this in various PowerShell environments.

Thank you!

P.S.

Regarding my test environments:

  • Example 1 was done using PowerShell 5.1.14409.1005 on Windows Server 2012 R2
  • Example 2 was done using PowerShell 5.1.17763.4720 on Windows Server 2019
Windows for business Windows Server User experience PowerShell
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Ewerton Jordão 5 Reputation points
    2023-08-14T21:03:52.73+00:00

    You can try use parameter /C to include some commands:

    Test-NetConnection localhost
    ComputerName : localhost
    RemoteAddress : ::1
    InterfaceAlias : Loopback Pseudo-Interface 1
    SourceAddress : ::1
    PingSucceeded : True
    PingReplyDetails (RTT) : 0 ms
    

    Or use arguments when calling external process like cmd.exe.

    #see all parameter available 
    cmd.exe /? 
    #Start external process
    start-process cmd.exe -ArgumentList "/C ping localhost"
    # or waiting execution in your session
    cmd.exe "/C ping localhost"
    
    

  2. MotoX80 36,291 Reputation points
    2023-08-16T13:09:48.5366667+00:00

    And PowerShell will dutifully execute each command at each prompt:

    When you execute them one by one, cmd.exe sees the ping statement by reading from stdin. (The "at each prompt".)

    When you paste the statements, Powershell.exe has to make Windows API calls to read the pasted data from the clipboard.

    https://learn.microsoft.com/en-us/windows/win32/dataxchg/clipboard-operations#paste-operations

    At this point Powershell has the 5 lines and can begin execution. It executes the write-host and launches cmd.exe. The "problem", as I see it, is that Powershell has no way to know that the next 2 lines (ping/exit) are intended for cmd.exe and need to be copied from the clipboard buffer and redirected to stdin (as part of launching cmd.exe). Or put back into the clipboard in a way that cmd.exe can recognize that it has data that it needs to read and process.

    You can have Powershell pass your commands via stdin or build a file and pass that as a parameter.

    Write-Host "=== START TEST ==="
    $crlf = "`r`n"
    $cmds = "@echo Hello from Cmd" + $crlf
    $cmds += "ping localhost -n 1" + $crlf
    $cmds += "@echo Goodbye from Cmd"  + $crlf
    $cmds | cmd.exe 
    Write-Host "=== SECOND TEST ==="
    $tmp = $env:TEMP + "\temp.bat"
    $cmds | Out-File $tmp  -Encoding ascii
    cmd.exe /c $tmp
    Write-Host "=== END TEST ==="
    
    

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.