Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return data from Powershell jobs without the Job-Information

i'm running a job which looks like this

$myjob =
{
  # regerate some $data
  return $data
}

I start and receive my job like this:

Start-Job -ScriptBlock $myjob -Name "job1"
Wait-Job -Name "job1"
$result = Receive-Job -Job "job1"

Now i want my $result to contain ONLY the $data which was returned. However, when inspecting $result besides of the $data i see much more information which I don't want to be included in my $data array. The messed-up data starts something like this:

(Returned Data:)

State         : Running
HasMoreData   : True
StatusMessage : 
Location      : localhost
Command       :  # regerate some $data
                 return $data
JobStateInfo  : Running
Finished      : System.Threading.ManualResetEvent
InstanceId    : f7c63b33-d270-4fa8-8042-111edf9d86a6
Id            : 270
Name          : job1
ChildJobs     : {Job271}
PSBeginTime   : 03.12.2012 14:06:26
PSEndTime     : 
PSJobTypeName : BackgroundJob
Output        : {}
Error         : {}
Progress      : {}
Verbose       : {}
Debug         : {}
Warning       : {}

this repeats over and over again like 20 times. After that my real $data is listed. However: iterateing over the $result array is not possible that way. What can i do?

like image 716
omni Avatar asked Dec 03 '12 13:12

omni


1 Answers

You are falling prey to a common misunderstanding about powershell: All uncaptured output in a script is returned to the caller, not just the arguments to "return." Example:

ps> $s = {
    1..3 # write 1,2,3 to output stream
    return 4 # write 4 to output stream, then exit scriptblock!
    5 # won't be output
    return 6 # won't be output either
}

ps> & $s
1
2
3
4

The return statement is used to exit a function early, and to optionally write one or more objects to the output stream (in addition to other outputs already emitted.)

If you don't want something to get output, then use one of the follow syntaxes:

$null = mycommand 
mycommand > $null
[void] (mycommand)

The reason you're seeing two extra "job" objects in your output is that both start-job and wait-job return the job object created and waited for, respectively. The reason for this is to allow pipelining:

$results = start-job { ... } | wait-job | receive-job 

What's happening here? Well, start-job creates a job and passes it to wait-job which waits until the job is complete, then passes the job to receive-job, which returns the results and is finally assigned to $results.

Following?

like image 185
x0n Avatar answered Nov 06 '22 23:11

x0n