我正在尝试使用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时出现错误时,在ScriptBlock中正确设置$ errortext ErrorVariable,因为文本:“Error in:显示错误。
Invoke-Command的ErrorVariable没有设置(我预期的)。
我的问题是:
以某种方式可以将Invoke-Command的ErrorVariable设置为ScriptBlock中的错误吗?
我知道我也可以使用InstalUtil,WMI和SC来安装服务,但目前这不相关。
答案 0 :(得分:17)
不,您无法将Errorvariable
调用中的Invoke-Command
设置为与脚本块中的相同。
但是,如果您的目标是“检测并处理scriptblock中的错误,并将错误返回到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
现在包含错误信息。
答案 1 :(得分:9)
Invoke-Command参数列表是一种单向交易。您可以在脚本中输出错误变量,例如在scriptblock的最后一行放置:
$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
一般来说,我认为在错误流上保留错误要好得多,与正常输出分开。
答案 2 :(得分:0)
从最严格的意义上讲,我认为答案是否定的,你不能将Invoke-Command的ErrorVariable设置为脚本块内ErrorVariable的内容。 ErrorVariable仅适用于它附加的命令。
但是,您可以将脚本块中的变量传递给Invoke-Command的范围。在您的代码中,使用-ErrorVariable errortext
运行New-Service命令。相反,通过在变量名称前加上“script:”来创建“脚本”范围内的变量,如下所示:-ErrorVariable script:errortext
。这使得变量在脚本块以及内部可用。
现在您的最后一行Write-Host("Error out: " + $errortext)
将输出脚本块内生成的错误。
答案 3 :(得分:0)
这几乎肯定不是“正确”的答案,但这是我希望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] }