在PowerShell中使用Start-Job时的-s

问题描述 投票:3回答:1

我试图在powershell中调用一个Start-Job。当我这样做时,它会产生一个带有以下参数的后台powershell:

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -Version 5.0 -s -NoLogo -NoProfile -EncodedCommand [encoded command I want to run in base64]

但是,无论我发送命令,powershell命令似乎永远不会完成。

我尝试生成这样的PowerShell实例:

powershell.exe -s

这似乎也创建了一个似乎被冻结的实例,而不是执行或做任何事情。在线查看,我似乎无法找到任何对-s参数的引用。

有没有人知道它是什么或如何摆脱它,以便我的开始工作正常工作?

编辑:-s可能是-sta的简写,但我的命令不会使用-sta冻结,但它确实使用-s。

Edit2:我后来发现-s是-ServerMode的简写,显然是Legacy Powershell 2.0选项。我不知道为什么在使用Start-Job时添加了它。

Edit3:我使用的命令是:

$deploymentsJobs += Start-Job -InitializationScript { SomeSmallFunction } (AnotherFunction) -ArgumentList  $arg1, $arg2, $arg3}
powershell command-line-interface start-job
1个回答
3
投票

tl;博士:

  • -s选项是命令行的预期部分,用于通过新的PowerShell进程启动后台作业 - 它将新进程置于服务器模式,这是与后台作业管理的调用进程通信所必需的。 它不是遗留选项,但也没有记录,因为它仅用于PowerShell内部使用。
  • 鉴于您描述的所有内容都符合预期,问题可能在于您通过-InitializationScript和主脚本块(隐含的-ScriptBlock参数)运行的特定命令。

正如您所发现的那样,Start-Job调用会在幕后产生powershell -s -NoLogo -NoProfile调用(可通过任务管理器发现)。 也就是说,创建了一个新的PowerShell进程以在后台运行命令。

如果使用-EncodedCommand参数调用Start-Process,则仅存在带有Base64编码的命令字符串的-Initialization参数 - 主脚本块((隐含的)-ScriptBlock参数)不通过命令行传递(参见下文)。

-s在PowerShell内部使用 - 总是 - 用于调用后台作业,而-s,正如您所发现的,是-servermode开关的别名。 (鉴于只记录了-STA,人们会期望-s-STA的缩写,但事实并非如此)。 -s / -servermode是一个实现细节,仅由PowerShell本身使用,这就是为什么它没有记录。

GitHub上的PowerShell Core源代码中的This location向您展示了如何构造后台进程的命令行。

服务器模式是后台进程必须处于的模式,以便通过其标准流(stdin,stdout,stderr)与调用进程通信:也就是说,在后台执行的命令通过其stdin发送到后台进程流,后台进程通过其stdout和stderr流报告其输出。[1]

请注意,在此进程间通信期间使用与P​​owerShell远程处理相同的基础结构进行序列化/反序列化。


[1] Ohad Schneider指出,如果主脚本块包含诸如Start-Process -NoNewWindow之类的命令,并且控制台程序直接写入后台进程'stdout流,则可能会意外中断此通信 - 请参阅this answer

© www.soinside.com 2019 - 2024. All rights reserved.