Powershell 调用命令并返回结果或错误
Powershell invoke command and getting result or error back
我有一个 powershell 脚本,如下所示。
$credential = Get-Credential
$server_list = @('server1','server2')
$script = "[System.Net.Dns]::GetHostName()"
foreach ($server_name in $server_list) {
$result = invoke-command -ComputerName $server_name -ScriptBlock { [System.Net.Dns]::GetHostName() }
write-output "Remote command execution result is $result"
}
有什么问题?
在下面的示例中,如果由于某种原因无法访问服务器或遇到拒绝访问错误,则不会填充结果的值。 $result 的值仅在成功执行时才会填充。
有时,我会收到以下错误。
Connecting to remote server server1 failed with the following error message: WinRM cannot process the request. The following error occured whilst using kerberos authentication: cannot find the computer server1. Verify that the computer exists on the network and that the name provided is spelled correctly.
现在,我想要实现的是,对于每台服务器,使用 [System.Net.Dns]::GetHostName()
或任何其他方式获取主机名、当前时间和 powershell 版本以及任何错误消息。将其存储在自定义对象等中,并将其 return 作为脚本块的一部分。这样,当我收到每个服务器的结果值时,我可以将结果加载到数据库中并分析哪些服务器遇到错误等。
我查看了 How to capture the Return Value of a ScriptBlock invoked with Powershell's Invoke-Command,这是一个很好的参考,但他们在那里所做的是一个 ping,在我的例子中,ping 并没有真正回答所使用的凭证是否有效等问题。
Invoke-Command 具有“通用参数”,如“ErrorVariable”。因此,您可以使用“-ErrorVariable ErrorVariableName”将错误对象分配给它。
然后您可以检查 ErrorVariableName 是否为 null 并对其进行处理。像这样:
$creds = Get-Credential
$server_list = @('server1','server2')
[System.Collections.Generic.List[pscustomobject]]$Output = @();
foreach ($server_name in $server_list) {
$result = invoke-command -ComputerName $server_name -ScriptBlock { [System.Net.Dns]::GetHostName() } -ErrorVariable ErrVar -Credential $creds
if ($ErrVar)
{
$Output.Add([PSCustomObject]@{
Server = $server_name
IsError = $true
Result = $ErrVar
})
}
else
{
$Output.Add([PSCustomObject]@{
Server = $server_name
IsError = $false
Result = $result
})
}
}
# do something with $Output
此外,查看错误变量本身,它有一些属性,如 ErrorCategory、StackTrace 等...如果您不想要完整的 StackTrace,只需要 CategoryInfo。
或者,您可以使用检查 try{} catch{}。由于 Invoke-Command 不是因错误而终止,因此您需要将 ErrorActionPreference 变量定义为 Stop,或使用 -ErrorAction Stop 使语句终止。
微软参考资料:
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_commonparameters?view=powershell-7.2
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_try_catch_finally?view=powershell-7.2
我有一个 powershell 脚本,如下所示。
$credential = Get-Credential
$server_list = @('server1','server2')
$script = "[System.Net.Dns]::GetHostName()"
foreach ($server_name in $server_list) {
$result = invoke-command -ComputerName $server_name -ScriptBlock { [System.Net.Dns]::GetHostName() }
write-output "Remote command execution result is $result"
}
有什么问题?
在下面的示例中,如果由于某种原因无法访问服务器或遇到拒绝访问错误,则不会填充结果的值。 $result 的值仅在成功执行时才会填充。
有时,我会收到以下错误。
Connecting to remote server server1 failed with the following error message: WinRM cannot process the request. The following error occured whilst using kerberos authentication: cannot find the computer server1. Verify that the computer exists on the network and that the name provided is spelled correctly.
现在,我想要实现的是,对于每台服务器,使用 [System.Net.Dns]::GetHostName()
或任何其他方式获取主机名、当前时间和 powershell 版本以及任何错误消息。将其存储在自定义对象等中,并将其 return 作为脚本块的一部分。这样,当我收到每个服务器的结果值时,我可以将结果加载到数据库中并分析哪些服务器遇到错误等。
我查看了 How to capture the Return Value of a ScriptBlock invoked with Powershell's Invoke-Command,这是一个很好的参考,但他们在那里所做的是一个 ping,在我的例子中,ping 并没有真正回答所使用的凭证是否有效等问题。
Invoke-Command 具有“通用参数”,如“ErrorVariable”。因此,您可以使用“-ErrorVariable ErrorVariableName”将错误对象分配给它。 然后您可以检查 ErrorVariableName 是否为 null 并对其进行处理。像这样:
$creds = Get-Credential
$server_list = @('server1','server2')
[System.Collections.Generic.List[pscustomobject]]$Output = @();
foreach ($server_name in $server_list) {
$result = invoke-command -ComputerName $server_name -ScriptBlock { [System.Net.Dns]::GetHostName() } -ErrorVariable ErrVar -Credential $creds
if ($ErrVar)
{
$Output.Add([PSCustomObject]@{
Server = $server_name
IsError = $true
Result = $ErrVar
})
}
else
{
$Output.Add([PSCustomObject]@{
Server = $server_name
IsError = $false
Result = $result
})
}
}
# do something with $Output
此外,查看错误变量本身,它有一些属性,如 ErrorCategory、StackTrace 等...如果您不想要完整的 StackTrace,只需要 CategoryInfo。
或者,您可以使用检查 try{} catch{}。由于 Invoke-Command 不是因错误而终止,因此您需要将 ErrorActionPreference 变量定义为 Stop,或使用 -ErrorAction Stop 使语句终止。
微软参考资料:
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_commonparameters?view=powershell-7.2 https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_try_catch_finally?view=powershell-7.2