Ответ 1
Вам нужно будет начать процесс:
start-process powershell -ArgumentList "sleep 10; cmd /c set > c:\env.txt" -WindowStyle hidden
Рассмотрим следующий код:
start-job -scriptblock { sleep 10; cmd /c set > c:\env.txt; }
exit
Исходное задание убивается при выходе родителя, поэтому вызов cmd.exe никогда не возникает. Я хотел бы написать какой-то аналогичный код, так что родительский элемент немедленно выйдет, а ребенок продолжает работать в фоновом режиме.
Я хотел бы сохранить все в одном script, если это возможно.
Вам нужно будет начать процесс:
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
Ваш script будет ждать завершения конца скриптового блока.
Если обнаружено, что использование Invoke-Command было в состоянии обойти ограничение, которое фоновое задание умеет с ним родительским. Приятно, что синтаксис почти такой же, как и для start-job, поэтому скриптовый блок можно сохранить как есть.
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-command подходит для запуска программ на другом компьютере, чтобы родительский элемент никогда не имел для него значения)
Если вы используете Start-Process, вы создаете новый дочерний процесс, в котором ваш сеанс powershell будет выполняться как его родительский процесс. Если вы упустите родительский процесс powershell, который начнет это, новый процесс будет потерян и продолжит работу. Однако он не сохранится, если вы убьете родительское дерево процессов
Start-Process -FilePath notepad.exe
Powershell не может запустить новый независимый процесс за пределами своего дерева процессов для вас. Однако это можно сделать в Windows с помощью CreateProcess, и эта функция доступна через WMI. К счастью, вы можете вызвать это из powershell:
Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList notepad.exe
Таким образом, новый процесс также будет продолжать работать, если дерево процессов будет убито, потому что новый процесс не имеет сеанса powershell в качестве родителя, а хост-процесс WMI.