我如何在Powershell中启动一个比它更长久的后台工作';谁的父母?

我如何在Powershell中启动一个比它更长久的后台工作';谁的父母?,powershell,Powershell,考虑以下代码: start-job -scriptblock { sleep 10; cmd /c set > c:\env.txt; } exit 当父级退出时,后台作业被终止,因此永远不会调用cmd.exe。我想编写一些类似的代码,这样父级立即退出,子级继续在后台运行 如果可能,我希望将所有内容保存在一个脚本中。您必须启动一个流程: start-process powershell -ArgumentList "sleep 10; cmd /c set > c:\env.txt

考虑以下代码:

start-job -scriptblock { sleep 10; cmd /c set > c:\env.txt; }
exit
当父级退出时,后台作业被终止,因此永远不会调用cmd.exe。我想编写一些类似的代码,这样父级立即退出,子级继续在后台运行


如果可能,我希望将所有内容保存在一个脚本中。

您必须启动一个流程:

start-process powershell -ArgumentList "sleep 10; cmd /c set > c:\env.txt" -WindowStyle hidden

你也可以这样做

$a = start-job -scriptblock { sleep 10; cmd /c set > c:\env.txt; }
Register-ObjectEvent -InputObject $a -EventName StateChanged -SourceIdentifier "finished"
$b = Wait-Event -SourceIdentifier "finished"
exit

脚本将等待scriptblock结束。

如果发现使用Invoke命令能够绕过后台作业与其父项一起终止的限制。很好的一点是,语法与start job几乎相同,因此scriptblock可以保持原样

start-job -scriptblock { sleep 10; cmd /c set > c:\env.txt; }
只会变成

Invoke-Command -ComputerName . -AsJob -scriptblock { sleep 10; cmd /c set > c:\env.txt; }

并且突然在其父进程死亡后幸存下来(可能是因为invoke命令适合在另一台计算机上运行程序,因此父进程对它来说永远不会有任何影响)

如果使用启动进程,则创建一个新的子进程,该子进程将您的powershell会话作为其父进程。如果您杀死启动此进程的powershell父进程,新进程将孤立并继续运行。但是,如果您杀死父进程树,它将无法生存

Powershell无法在其进程树之外为您启动新的独立进程。但是,这可以在Windows中使用CreateProcess完成,并且此功能通过WMI公开。幸运的是,您可以从powershell调用:

Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList notepad.exe

这样,如果进程树被终止,新进程也将继续运行,因为新进程没有您的powershell会话作为父进程,而是WMI主机进程。

这与使用Wait job不一样吗?我想说的是,OP不希望这样。他们想要的是,当父项关闭(并且应该关闭)时,作业仍在运行,但不应等待作业。但我可能在这方面错了:)我不知道,事实上我不介意,我只是给了另一种方式,而且等待的时间更短,它可以帮助其他人。似乎本地操作也需要它。
Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList notepad.exe