19

我正在尝试使用 powershell 在远程计算机上安装服务。

到目前为止,我有以下内容:

Invoke-Command -ComputerName  $remoteComputerName -ScriptBlock {
         param($password=$password,$username=$username) 
         $secpasswd = ConvertTo-SecureString $password -AsPlainText -Force
         $credentials = New-Object System.Management.Automation.PSCredential ($username, $secpasswd)
         New-Service -Name "XXX" -BinaryPathName "c:\XXX.exe" -DisplayName "XXX XXX XXX" -Description "XXXXXX." -Credential $credentials -ErrorVariable errortext 
         Write-Host("Error in: " + $errortext)
        } -ArgumentList $password,$username -ErrorVariable errortext 


Write-Host("Error out: " + $errortext)

当执行 New-Service 时出现错误时,$errortext ErrorVariable 会在 ScriptBlock 内正确设置,因为文本:“Error in: 向我显示错误。

Invoke-Command 的 ErrorVariable 未设置(这是我的预期)。

我的问题是:

是否可以将 Invoke-Command 的 ErrorVariable 设置为我在 ScriptBlock 中遇到的错误?

我知道我也可以使用 InstalUtil、WMI 和 SC 来安装服务,但目前这不相关。

4

4 回答 4

23

不,您无法ErrorvariableInvoke-Command调用中的设置与脚本块中的设置相同。

但是,如果您的目标是“检测和处理脚本块中的错误,并将错误返回到Invoke-Command调用者的上下文”,那么只需手动执行:

$results = Invoke-Command -ComputerName server.contoso.com -ScriptBlock {
   try
   {
       New-Service -ErrorAction 1
   }
   catch
   {
       <log to file, do cleanup, etc>
       return $_
   }
   <do stuff that should only execute when there are no failures>
}

$results现在包含错误信息。

于 2012-09-26T20:01:01.143 回答
12

Invoke-Command 参数列表是一种单向处理。您可以在脚本中输出错误变量,例如在脚本块的最后一行放置:

$errortext

或者更好的是,根本不要通过 -ErrorVariable 捕获错误。即使通过远程连接,脚本块输出(包括错误)也会流回调用者。

C:\> Invoke-Command -cn localhost { Get-Process xyzzy } -ErrorVariable errmsg 2>$null
C:\> $errmsg
Cannot find a process with the name "xyzzy". Verify the process name and call the cmdlet again.
    + CategoryInfo          : ObjectNotFound: (xyzzy:String) [Get-Process], ProcessCommandException
    + FullyQualifiedErrorId : NoProcessFoundForGivenName,Microsoft.PowerShell.Commands.GetProcessCommand
    + PSComputerName        : localhost

一般来说,我认为最好将错误保留在错误流中,与正常输出分开。

于 2012-09-26T13:44:09.150 回答
4

这几乎肯定不是“正确”的答案,但是当我希望 Invoke-Command 在脚本中抛出错误时,我会使用它。

$error.Clear()
Invoke-Command -ComputerName localhost -ScriptBlock {Command-ThatFails}
$if ($error.Count -gt 0) { throw $error[0] }

如果您想将错误保留在变量中,可以执行以下操作:

$error.Clear()
Invoke-Command -ComputerName localhost -ScriptBlock {Command-ThatFails}
$if ($error.Count -gt 0) { $myErrorVariable = $error[0] }
于 2019-04-17T19:57:35.393 回答
0

在最严格的意义上,我相信答案是否定的,你不能将 Invoke-Command 的 ErrorVariable 设置为脚本块内 ErrorVariable 的内容。ErrorVariable 仅适用于它所附加的命令。

但是,您可以将脚本块中的变量传递给 Invoke-Command 的范围。在您的代码中,您使用-ErrorVariable errortext. 相反,在“脚本”范围内创建变量,方法是在变量名称前加上“脚本:”,如下所示:-ErrorVariable script:errortext。这使得变量在脚本块之外和内部都可用。

现在您的最后一行Write-Host("Error out: " + $errortext)将输出在脚本块内生成的错误。

更多信息在这里这里

于 2017-06-27T15:15:09.990 回答