如何防止Powershell在通过SSH派生时杀死自己的后台进程



我们在C:testtest.ps1中有一个Powershell脚本。该脚本包含以下内容(未删除任何内容(:

Start-Process -NoNewWindow powershell { sleep 30; }
sleep 10

当我们打开命令行窗口(cmd.exe(并通过以下命令执行该脚本时

c:WindowsSystem32WindowsPowerShellv1.0powershell.exe -File C:testtest.ps1

我们可以在Windows任务管理器(以及Sysinternals Process Explorer(中看到,脚本的行为与预期一致:

  • 在执行了上述命令之后,进程列表中立即出现两个新条目,其中一个是Powershell执行";主";脚本(test.ps1(,其中一个是执行"脚本"的Powershell;背景脚本";({ sleep 30; }(
  • 10秒后,第一个条目(与test.ps1相关(从进程列表中消失,而第二个条目保留在进程列表中
  • 当额外的20秒(即总共30秒(过去时,第二个条目(与{ sleep 30; }相关(也会从进程列表中消失

这是预期的行为,因为除非给定-Wait,否则Start-Process无论如何都会在后台启动新进程。到目前为止,一切都很好。

但现在我们遇到了一个棘手的问题,这个问题已经花了我们两天的调试时间,直到我们最终找出其中一个脚本行为不端的原因:

实际上,test.ps1是通过SSH执行的

也就是说,我们已经在Windows server 2019上安装了微软的OpenSSH服务器实现,并对其进行了正确配置。使用其他机器(Linux和Windows(上的SSH客户端,我们可以登录到Windows Server,通过在客户端上执行以下命令,我们可以通过SSH在服务器上执行test.ps1

ssh -i <appropriate_key> administrator@ip.of.windows.server c:WindowsSystem32WindowsPowerShellv1.0powershell.exe -File C:testtest.ps1

在观察Windows Server上的任务管理器时,一旦在客户端上执行此命令,我们就可以再次看到进程列表中的两个新条目,如上所述。

但是,这两个条目将在10秒钟后从服务器上的进程列表中消失

这意味着一旦主进程结束,后台进程({ sleep 30; }(就会被终止。这与记录在案的情况和应该发生的情况相反,我们真的需要防止它

所以问题是:

我们如何更改test.ps1,使后台进程({ sleep 30; }(在脚本结束时的任何情况下都不会被杀死,即使脚本是通过SSH启动的?

一些旁注:

  • 这不是一个学术性的例子。实际上,我们在服务器上有一个相当复杂的脚本系统,它由大约十几个Powershell脚本组成,其中一个是";主";如上所示,在后台执行其他脚本的脚本;背景脚本本身反过来可能启动进一步的背景脚本。

  • 重要的是首先不要通过SSH在后台启动主脚本。客户端必须处理主脚本的输出和退出代码,并且必须等待主脚本完成一些工作并返回。

    这意味着我们必须使用Powershell的功能来启动主脚本中的后台进程(或者启动能够启动后台进程的第三方程序,这些后台进程在主脚本结束时不会被杀死(。

注意:在此处使用作业的原始建议是不正确的,因为当作业与父会话一起停止时,任何子进程仍然会被终止。由于这是对这种情况的错误建议,我已经从这个答案中删除了该内容。

不幸的是,当PowerShell会话结束时,从该会话创建的子进程也会结束。但是,当使用PSRemoting时,我们可以使用-InDisconnectedSession参数(别名为-Disconnected(告诉Invoke-Command在断开连接的会话中运行命令:

$icArgs = @{
ComputerName = 'RemoteComputerName'
Credential = ( Get-Credential )
Disconnected = $true
}
Invoke-Command @icArcs { ping -t 127.0.0.1 }

根据我使用无限ping进行的测试,如果父PowerShell会话关闭,则远程会话应继续执行。在我的情况下,ping命令继续运行,直到我自己在远程服务器上停止了进程。

这里的缺点是,您似乎没有使用PowerShell远程处理,而是通过SSH调用shell命令,而SSH恰好是PowerShell脚本。如果需要PowerShell远程处理的SSH传输,则还必须使用PowerShell Core。

最新更新