4

If I want to run a Powershell script (v. 7.1.5), detached, as in I can close the cmd window, log off, come back, log in, and it still be running like in Linux, is that possible without using the task scheduler?

I have seen a lot of questions on SO about this, but nothing seems to work like & or nohup in Linux. I am on Windows Server 2016, if that matters. I have seen this (and many others on SO):

Powershell equivalent of bash ampersand (&) for forking/running background processes

If I want to run this,

   foreach($n in (0..100)) {
        write-host "Hello World $n" 
        start-sleep -seconds 2
    }

I can see the job and what it produces with receive-job [job_number]. If I close my session window, it dies. I thought if I used:

start-job -name BackgroundJob -FilePath C:\temp\test.ps1

it would stay and I also tried .\test.ps1 &

The script always dies when I close my cmd window.

  • How do I keep everything running?
  • I could do a Scheduled task to run the script every minute and not run it if it is already running, but could that bog down the server checking that much?
  • I could also hide the window when starting, but this doesn't really seem to be the same thing (is it?)
  • Is nohup and & in Linux fooling me by simply running something and hiding the window (what if I log out?
learntofix
  • 87
  • 5
  • 3
    On Windows, if you use `Start-Process` (possibly with `-WindowStyle Hidden`), the launched process lives on independently of the calling PowerShell session, but is still tied to the current user's OS session. _Maybe_ using [`psexec`](https://learn.microsoft.com/en-us/sysinternals/downloads/psexec) with the `-s` (run as `NT Authority\System`) option - and `-d`, to launch _asynchronously_ - offers a solution. – mklement0 Oct 29 '21 at 17:00
  • Might be possible creating a Windows Service that runs as NT Authority. – Santiago Squarzon Oct 29 '21 at 17:03

1 Answers1

1

You can use register-scheduledjob at an elevated prompt. Then you can logout and log back in, and when the job finishes, you can use the regular job commandlets to process it. You can find the jobs in the task scheduler under \Microsoft\Windows\Powershell\ScheduledJobs. The output of a scheduled job can be serialized objects, just like the output of a job.

$trigger = New-JobTrigger -Once -At 1:57pm
Register-ScheduledJob test {sleep 1; 'done'} -trigger $trigger


get-scheduledjob

Id         Name            JobTriggers     Command                Enabled
--         ----            -----------     -------                -------
3          test            1               sleep 1; 'done'        True


get-job

Id     Name PSJobTypeName   State         HasMoreData Location  Command
--     ---- -------------   -----         ----------- --------  -------
1      test PSScheduledJob  Completed     True        localhost sleep 1; 'done'


get-job | receive-job -keep

done

js2010
  • 23,033
  • 6
  • 64
  • 66
  • It won't let me give you an upvote because of my rep., but I did have a question. Is this the same as me creating the task through the regular Windows Task Scheduler? – learntofix Oct 29 '21 at 19:56
  • It's a bit more integrated with powershell jobs. It outputs to an xml file somewhere. – js2010 Oct 29 '21 at 19:59