How to stop child processes in remote session?

Hi,

I have a problem I’m not quite sure how to solve, and if anyone have suggestions, I’d be happy.

We have a setup where PSU (currently latest 2.x, yes we will update during spring) via a job starts a session to a remote session and starts a process (robocopy.exe via robocopyps) which may take a long time. If the job is e.g. cancelled, the process will continue until done even if the job in PSU stops running.

I would like the process on the remote computer to stop if at all possible.

Essentially it’s something along (pseudocode):

$Session = New-PSSession somehost
Invoke-Command -Session $Session -ScriptBlock {
Robocopy.exe something tosomewhere
}

Any ideas would be most appreciated.

Product: PowerShell Universal
Version: 2.12.6

In general, I can find the processes and kill them with:

Get-Process | `
  Where-Object {$_.SessionId -eq ([System.Diagnostics.Process]::GetCurrentProcess().SessionId) -and $_.ProcessName -eq "Robocopy"} | `
  Stop-Process -Force

But I have nowhere to trap the exit so that I can get those lines running, as far as I can tell.

Starting to think that I should add my own stop-job solution in the dashboard to cancel the job in PSU and do the cleanup.

But on this tack, an idea would be to make it possible to hook into the cancellation of jobs in order to do cleanup tasks.

Hi again, still thinking aloud. Maybe I’ve found the case for moving to PS 7.3 from 7.2 on my clients. With PS 7.3 I should be able to add a clean {} block to achieve this?

I guess not :frowning:

Sounds like you want to create a new script and attach it to a trigger when the original script (job) is cancelled.

No idea if its supported on PSU 2.x though. Documentation even for PSU 3.x doesn’t list it as a trigger. Can’t find it in the changelog either.

1 Like

Yes, that’s a reasonable idea, that was my next option, and I believe it is supported but haven’t tried it. It has some drawbacks though. There are two hosts involved and a number of parallell jobs, so I would have to figure out where the script have gotten to, and/or the exact processes it started which isn’t very simple at least.

Might be if I, e.g., emitted the processes to the output so I could fetch it there, will look into that.

I’m a little curios as to what exactly happens to my script when it is “cancelled”?

Well, when it’s cancelled it’s going to stop executing the code block. However, because you are calling an external .exe, stopping the PowerShell session isn’t going to close Robocopy.

Maybe try setting a $cache: variable when the process is started on the individual hosts? Assuming you are using foreach…

$Cache:HostsStarted = New-Object System.Collections.Generic.List[string]
Foreach ($Computer in $Computers) {
    $Session = New-PSSession $Computer 
    Invoke-Command -Session $Session -ScriptBlock {
        Robocopy.exe $Something $ToSomewhere
    }
    $Cache:HostsStarted.add($Computer)
}

Depending on how you have your environments setup, you may need to add it as a server-wide cache object.

To do that, it would look something like this…

$HostsStarted = New-Object System.Collections.Generic.List[string]
Foreach ($Computer in $Computers) {
    $Session = New-PSSession $Computer 
    Invoke-Command -Session $Session -ScriptBlock {
        Robocopy.exe $Something $ToSomewhere
    }
    $HostsStarted.add($Computer)
    Set-PSUCache -Key HostsStarted -Value $HostsStarted
}

To take it a step further, if there are ever multiple of the jobs running, you could do something like…

Set-PSUCache -Key "HostsStarted$($UAJobId)" -Value $HostsStarted

By including the JobID which is always unique as part of the variable name, you would be able to know which computers had the robocopy job started on them per job.

1 Like