I'm trying to achieve this with a code:
- ☑ Run a command
- ☑ Wait X seconds
- ☐ If command completed and is successful i return 1
- ☐ If command completed and is not successful i return 0
- ☑ If command did not completed I return 0.
I don't need it to be asynchronous. This is my first code:
$timeoutSeconds = 10
$code = {
ping something
}
$job = Start-Job -ScriptBlock $code
if (Wait-Job $job -Timeout $timeoutSeconds) { Receive-Job $job }
Remove-Job -force $job
if ($job.State -eq 'Completed'){
$ExitCode = 0
}
else {
$ExitCode = 1
}
My Powershell
[System.Environment]::OSVersion.Version
Major Minor Build Revision
----- ----- ----- --------
6 2 9200 0
I would like this to be not only for my powershell version.
I tried to add a return inside my $code
$code = {
ping something
return $LASTEXITCODE
}
But I can't find anything inside my $job
.
I tried to assign Receive-Job
to a variable, but it doesn't get never populated.
if (Wait-Job $job -Timeout $timeoutSeconds) { $r = Receive-Job $job }
$r
is alwasys empty (in both cases: Wait-Job reach or not the timeout).
I want to get the $LASTEXITCODE
i'm returning in my $code
block, I would like something like:
$timeoutSeconds = 10
$code = {
ping 2.3.1.2
return $LASTEXITCODE
}
$job = Start-Job -ScriptBlock $code
if (Wait-Job $job -Timeout $timeoutSeconds) { Receive-Job $job }
Remove-Job -force $job
if ($job.State -eq 'Completed'){
$ExitCode = $job.ReturnedValue #this doesn't exists
}
else {
$ExitCode = 1
}
Write-Output $ExitCode
My problem is how to discern if:
- Job completed in less than timeout because it succeeded
- Job completed in less than timeout because it failed faster than I thought.
The command I'm running is a software command I would like to leave unkown, it is a something like a ping but:
- the command finish in less than 10 seconds when it works (return 0)
- the command finish in more than 10 seconds (30 or more) when the resource is unreachable (return 1)
- the command finish in less than 10 seconds when something went wrong (return 1)
If the case is 2
the job is not completed.
If the case is either 1
or 2
I need the returned value inside the $code
block to understand if the command is good or not.
How do I get the returned value inside the $code
block outside after the job is completed? (if job is not completed I'm aware I can't have it, but I should be able to use the result of a job)
Thanks
CodePudding user response:
If Wait-Job -Timeout <timeoutInSeconds>
returns the job object then you know the job completed in time. If a terminating error occurred that caused the job to exit prematurely, the State
property on the job object will reflect this, so simply do:
$timeoutSeconds = 10
$completedInTime = $false
$code = {
MyCommands
}
# start job, wait for timeout
$job = Start-Job -ScriptBlock $code
if($job |Wait-Job -Timeout $timeoutSeconds){
# If it completed successfully, State will have the value `Completed`
$completedInTime = $job.State -eq 'Completed'
$results = $job |Receive-Job
}
$job |Remove-Job -Force
# `$true` = 1
# `$false` = 0
$ExitCode = [int]$completedInTime
CodePudding user response:
Thanks to @Mathias R. Jessen I achieved this:
$timeoutSeconds = 10
$completedInTime = $false
$code = {
ping 2.13.1.2 /n 1 > null # this way results won't have this output that I don't need
return $LASTEXITCODE
}
# start job, wait for timeout
$job = Start-Job -ScriptBlock $code
if($job |Wait-Job -Timeout $timeoutSeconds){
# If it completed successfully, State will have the value `Completed`
if($job.State -eq 'Completed'){
# Only in this case results will hold the LASTEXITCODE I returned in code block
$results = $job |Receive-Job
if ($results -eq 0){
$ExitCode = 0
}
else {
$ExitCode = 1
}
}
else{
# In this case I know the command is failing
$ExitCode = 1
}
}
$job |Remove-Job -Force
Write-Output $ExitCode