Получите выходные данные Write-Host и код выхода из Invoke-Command в удаленной системе

У меня есть скрипт, расположенный в удаленной системе.

На сервере "web12" в C:\tmp\hgttg.ps1:

 Write-Host "Don't Panic"
 exit 42

Я вызываю этот скрипт из моего локального ящика (обе системы работают под управлением v4.0), используя Invoke-Command:

$svr = "web12"
$cmd = "C:\tmp\hgttg.ps1"
$result = Invoke-Command -ComputerName $svr -ScriptBlock {& $using:cmd}

Это приводит к следующему выводу при выполнении:

> $result = Invoke-Command -ComputerName $svr -ScriptBlock {& $using:cmd}
Don't Panic
> $result
>

($ result не установлен, вывод идет прямо на консоль, ничего хорошего!) После долгих поисков в сети и поиска неисправностей я пришел к некоторому улучшению:

> $result = Invoke-Command -ComputerName $svr -ScriptBlock {& $using:cmd; $LASTEXITCODE}
Don't Panic
> $result
42
>

Теперь я могу захватить код возврата, но вывод все равно идет прямо на консоль. Это насколько я могу получить. В длинном списке вещей, которые я уже пытался, ни одно из следующего не сработало:

  • Вместо '&' использовал 'Invoke-Expression' с -OutVariable out; New-Object -TypeName PSCustomObject -Property @{code=$LASTEXITCODE; выход = $ из}

Это производит вывод:

> $result
code           : 42
output         : 
PSComputerName : web12
RunspaceId     : aaa00a00-d1fa-4dd6-123b-aa00a00000000
> 
  • Попытка обеих итераций выше с '4>&1' и '*>&1' в конце внутренней и внешней команд, без изменений.

  • Попытка каждого из:

    1. "& $ using: cmd | Tee-Object -Variable out; $ out"
    2. "& $ using: cmd> $ out; $ out"
    3. "$ out = & $ using: cmd; $ out"

    (Сброс кода возврата только для получения результата) Опять без изменений.

  • Также попытались: '& $using:cmd >> C:\tmp\output.log; $LASTEXITCODE. Сгенерированный файл был пуст, а текст по-прежнему выводился на локальный терминал.

Я уверен, что есть что-то очевидное, что я упускаю, но пока все, что я ударил, это тупики. Какие-либо предложения?

1 ответ

Решение

На PSv4- (версии 4.x или ниже) вы просто не можете захватить Write-Host вывод - он всегда идет прямо к консоли.

В PSv5+, Write-Host (тоже) записывает во вновь введенный информационный поток, что недавно введенный Write-Information Командлет предназначен для записи в; его номер 6,

Таким образом, если ваш целевой хост работает с PSv5+, вы можете использовать следующее; обратите внимание, как *> захватывает все выходные потоки путем перенаправления (&) их в поток успеха (1), но вы можете использовать 6> захватить поток информации выборочно):

$result = Invoke-Command -ComputerName $svr -ScriptBlock {& $using:cmd *>&1; $LASTEXITCODE}
$output = $result[0..($result.Count-2)]
$exitCode = $result[-1]
Другие вопросы по тегам