Возврат данных из заданий Powershell без информации о задании

я выполняю работу, которая выглядит так

$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

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

Если вы не хотите, чтобы что-то выводилось, используйте один из следующих синтаксисов:

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

Причина, по которой вы видите два дополнительных объекта «задание» в своем выводе, заключается в том, что оба 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
Почти идеально! но вместо деталей, которые я разместил в блоке кода Returned-Data, я все еще получаю две возвращаемые записи 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