"Windows SSH-launched server process dies when the SSH session closes"
▸ SYMPTOM
You SSH into a Windows box, start a long-running process (e.g. a dedicated game server), and it looks like it worked. But the moment the SSH session closes -- or the command returns -- the server process is gone. Get-Process from a new session shows nothing running.
This also silently invalidates test results: if you launch a server in one SSH session and check it from another, the server was already dead before your test ran.
▸ CAUSE
Windows OpenSSH sshd tears down all child processes when the session disconnects. Unlike Unix, where a backgrounded or nohup'd process survives shell exit, Windows Start-Process and -WindowStyle Hidden do not escape the session's process tree. The server process is a child of the sshd session and is killed on disconnect.
▸ FIX
Launch the server as a Scheduled Task -- task-launched processes are not tied to any SSH session:
# Create a scheduled task that runs at system boot
$action = New-ScheduledTaskAction `
-Execute "C:\server\sbox-server.exe" `
-Argument "+game org.yourpackage" `
-WorkingDirectory "C:\server"
$trigger = New-ScheduledTaskTrigger -AtStartup
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -RunLevel Highest
Register-ScheduledTask -TaskName "SboxServer" `
-Action $action -Trigger $trigger -Principal $principal
# Start it now (without waiting for a reboot)
Start-ScheduledTask -TaskName "SboxServer"For crash recovery, add a flag-file-armed watchdog task that relaunches the server if it exits -- this covers both boot and unexpected crashes.
When testing over SSH: keep the launch, the test, and the assertion in one SSH session, or the server will be dead before the test runs.
▸ WHY IT WORKS
Scheduled Tasks run under the Task Scheduler service, which owns the process tree independently of any interactive or SSH session. The process lifetime is tied to the task definition, not to whoever triggered it. This is the standard pattern for any long-running process on a remote Windows box managed over SSH.