3

我有一个位于远程系统上的脚本。

在 C:\tmp\hgttg.ps1 下的服务器“web12”上:

 Write-Host "Don't Panic"
 exit 42

我使用 Invoke-Command 从本地机器(运行 v4.0 的两个系统)调用此脚本:

$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; 新对象 -TypeName PSCustomObject -Property @{code=$LASTEXITCODE; 输出=$out}

这将产生输出:

> $result
code           : 42
output         : 
PSComputerName : web12
RunspaceId     : aaa00a00-d1fa-4dd6-123b-aa00a00000000
> 
  • 在内部和外部命令的末尾尝试使用 '4>&1' 和 '*>&1' 进行上述两次迭代,没有变化。

  • 尝试了以下各项:

    1. "& $using:cmd | Tee-Object - 变量输出;$out"
    2. "& $using:cmd >$out; $out"
    3. "$out = & $using:cmd; $out"

    (丢弃返回码只是为了获得输出)同样,没有变化。

  • 还尝试:'& $using:cmd >> C:\tmp\output.log; $LASTEXITCODE'。生成的文件是空的,文本仍然输出到本地终端。

我敢肯定,我缺少一些明显的东西,但到目前为止,我所遇到的都是死胡同。有什么建议么?

4

1 回答 1

4

PSv4-(版本 4.x 或更低版本)上,您根本无法捕获Write-Host输出- 它总是直接进入控制台。

PSv5+ 中,Write-Host(也)写入新引入的 cmdlet 旨在写入的新引入Write-Information信息流;它的编号是6

因此,如果您的目标主机运行 PSv5+,您可以使用以下内容;请注意如何通过将 ( ) 重定向到成功流 ( ) 来*>捕获所有输出流,但您可以使用它来选择性地捕获信息流):&16>

$result = Invoke-Command -ComputerName $svr -ScriptBlock {& $using:cmd *>&1; $LASTEXITCODE}
$output = $result[0..($result.Count-2)]
$exitCode = $result[-1]
于 2018-03-28T03:27:24.700 回答