How to send multiple statements to the same .cmd i

2019-09-17 20:22发布

问题:

How can I send multiple commands to the same instance of a .cmd script? Doing so from either cmd or powershell is acceptable.

I'm not trying to to send multiple commands in a single concatenated statement-- character-limits could be a factor with very large scripts. Rather, I want to send multiple commands, as separate statements, to a running .cmd script. When I say ".cmd", I do not mean "cmd.exe"-- I mean a custom shell script, saved to disk with a .cmd extension.

Specifically, this post shows how to create a powershell4.cmd script which launches a .Net 4.0 PowerShell. I want to send a sequence of commands to that powershell.

For example, is it possible to get a handle to that new shell, in order to send additional commands to it?

回答1:

Another approach might be to put the save the commands you want to send in a file (e.g. test.in) and then use a command like this:

Start-Process -RedirectStandardInput test.in cmd 

Consider adding -Wait and -NoNewWindow. You would need to experiment some to see how this interacts with a batch script.

I don't believe PowerShell natively supports redirecting to a pipe, but it might be doable by calling the .NET runtime.



回答2:

Here's a simple way of sending multiple commands to a single instance of cmd.exe:

cmd /c "echo before & pwd & echo after"

While it might be possible to create a process running cmd with a redirected standard input, that might be substantially more complicated.

P.S. If you use double ampersands as the command separator, the later command will only run if the earlier command return a success exit code.



回答3:

Here's the answer, at a Windows command-line:

powershell .\ps4.cmd 'PowerShell.exe -ExecutionPolicy Bypass -File .\zipper.ps1'


Explanation:

My solution is based on putting the script into a script file, and executing. In code below, ps4.cmd is the PowerShell script mentioned in the OP. Commands below are executed at a powershell prompt:

  1. .\ps4.cmd .\zipper.ps1

    .\ ensures the powershell will look for the scripts in the active directory.

or,

  1. .\ps4 'Get-Content .\zipper.ps1 | Invoke-Expression'

    equivalent to:

    .\ps4 'GC .\zipper.ps1 | iex'


Execution Policy

By default, Windows ExecutionPolicy is "restricted", which will prevent any scripts from running. Changing ExecutionPolicy system-wide requires Admin access. I'm including workarounds for this since, in my use-case, it's a critical blocker-- even if you change the security policy for powershell, that might not apply to the ps4.cmd environment.

Here are a couple ways to bypass the security restriction without Admin access:

  1. PowerShell.exe -ExecutionPolicy Bypass -File .\zipper.ps1

    So, how can we pass the script to ps4.cmd and bypass security?

    .\ps4.cmd 'PowerShell.exe -ExecutionPolicy Bypass -File .\zipper.ps1'

    • the single-quotes are not required, unless there are spaces in your script names or paths.

    • To run from the Windows command-line (wish i could make this terser, but it's the answer):

    powershell .\ps4.cmd 'PowerShell.exe -ExecutionPolicy Bypass -File .\zipper.ps1'

or,

  1. .\ps4 'GC .\zipper.ps1 | iex'

    Yep, same as #2 above. We pass a script to the external script and bypass security-restriction, in one simple statement. For its terseness, this would be my preferred answer, but my concern about the GC method is-- are we really executing individual statements? Or just one big string? If it's just one big string, then this does not satisfy the OP.

Note, plz do not flag this answer as a "security exploit"--

Microsoft never intended [execution policy] to be a security control. Which is why there are so many options for bypassing it. Microsoft was nice enough to provide some native options https://diigo.com/08xzeu