Връщане на данни от задания на Powershell без Job-Information

изпълнявам работа, която изглежда така

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

Започвам и получавам работата си така:

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

Сега искам моят $result да съдържа САМО $data, който беше върнат. Въпреки това, когато проверявам $result освен $data, виждам много повече информация, която не искам да бъде включена в моя масив $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       : {}

това се повтаря отново и отново като 20 пъти. След това моят истински $data е посочен. Обаче: повторението над масива $result не е възможно по този начин. Какво мога да направя?


person omni    schedule 03.12.2012    source източник


Отговори (3)


Вие ставате жертва на често срещано недоразумение относно powershell: целият незахванат изход в скрипта се връща на извикващия, а не само аргументите за „връщане“. Пример:

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

Инструкцията за връщане се използва за ранно излизане от функция и за незадължително записване на един или повече обекти в изходния поток (в допълнение към други вече изведени изходи.)

Ако не искате нещо да се изведе, използвайте един от следните синтаксиси:

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

Причината да виждате два допълнителни обекта "job" във вашия изход е, че и start-job, и wait-job връщат съответно създадения и чакан обект за работа. Причината за това е да се позволи тръбопровод:

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

какво се случва тук Е, start-job създава задание и го предава на wait-job, което изчаква, докато заданието приключи, след което предава заданието на receive-job, което връща резултатите и накрая се присвоява на $results.

Следите?

person x0n    schedule 03.12.2012
comment
Е, това беше поучително и реши проблема! Благодаря ти! - person omni; 03.12.2012

И аз имах същия проблем. Донякъде го заобиколих, като не използвах ключовата дума return; вместо да излезете с return $data, опитайте просто да използвате $data като последен израз във вашето отдалечено задание:

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

Не знам обаче защо това изглежда работи.

Извиквам и моите отдалечени работни места по този начин:

$job = Invoke-Command -ComputerName $servers -FilePath $myRemoteScript -ArgumentList $myArgs -AsJob -JobName $jobName | Get-Job | Wait-Job
$data = Receive-Job -Job $job
person Patrick Cuff    schedule 03.12.2012
comment
Почти перфектно! но вместо подробностите, които публикувах в кодовия блок Върнати данни, все още получавам върнати два System.Management.Automation.PSRemotingJob записа (типовете на тези обекти) преди действителните $data. Някакви идеи? - person omni; 03.12.2012
comment
Ключовата дума return не е единственият начин за връщане на неща от скриптове. Вижте отговора ми по-горе. - person x0n; 03.12.2012

Аз също се сблъсках със същия проблем, при който искам да изключа коментари. Така че най-лесното решение е да напишете коментарите си, като използвате:

Write-Host("Your comments ") -Fore Red

person asif    schedule 21.09.2017