Home > front end >  Need to run app on N remotes hosts and handle them all
Need to run app on N remotes hosts and handle them all

Time:09-05

Im using this code to run app on N remote hosts and need to wait until all of them are finished and get their results. But the execution just passes throuhg, all jobs are being marked Completed and code exits. How to make it wait till apps finished their execution?

$procArray = [System.Collections.ArrayList]@()

foreach ($key in $simulatorServers.keys) {

    $unitHost = $simulatorServers[$key][0]
    $EXE="C:\app.exe"
    Wr-DebugReg "Running $EXE on $unitHost "
    $ScriptString="Start-Process -FilePath $EXE "
    $ScriptBlock=[System.Management.Automation.ScriptBlock]::Create($ScriptString)
    $Session=New-PSSession -ComputerName $unitHost -EnableNetworkAccess -Name "session$counter" -Credential $crNonProd
    $rez2 = Invoke-Command -Session $Session -ScriptBlock $ScriptBlock -AsJob
    $rez00=$procArray.Add($rez2)
    Wr-DebugReg "Running process id=$($rez2.id) name=$($proc.Name)on $unitHost"
    Wr-DebugReg ""
}
$procArray | Wait-Job
$procArray | Receive-Job

these jobs gone to status Completed even if launched processes still running enter image description here

CodePudding user response:

let invoke-command handle the the amount of jobs/sessions to open in parallel - you will receive 1 job with childs:

$scriptBlock = {
    start-process -FilePath 'C:\app.exe' 
}

$sessions = @(
    foreach ($key in $simulatorServers.keys) {
        $unitHost = $simulatorServers[$key][0]
        New-PSSession -ComputerName $unitHost -EnableNetworkAccess -Name "session$counter" -Credential $crNonProd
    }
)

$job = Invoke-Command -Session $Sessions -ScriptBlock $ScriptBlock -AsJob

$result = receive-job -Wait -Job $job

btw. I do not see, based on this sample, what you want to receive. you want to execute "start-process -FilePath 'C:\app.exe' " on the target machines but this won't give you anything back.

to get the information back modify the scriptblock like this:

$scriptBlock = {
    $result = start-process -FilePath 'C:\app.exe' -wait -PassThru
    return $result
}

CodePudding user response:

This is the answer. This code is working, it waits till all jobs are finished. -wait is the key thing.

$procArray = [System.Collections.ArrayList]@()

foreach ($key in $hosts.keys) {

        $unitHost = $hosts[$key][0]
        $EXE="c:\app.exe"  

        $Session=New-PSSession -ComputerName $unitHost -EnableNetworkAccess -Name "session$counter" -Credential $crNonProd
        $rez2 = Invoke-Command -Session $Session -ScriptBlock {Start-Process -FilePath $args[0] -Wait} -ArgumentList  $EXE -AsJob
        $rez00=$procArray.Add($rez2)
        Wr-DebugReg "Starting process id=$($rez2.id) name=$($proc.Name)on $unitHost"
        Wr-DebugReg ""

}

while ( $procArray.State -contains 'Running') { Start-Sleep -Seconds 1 }

  • Related