如何在主机未知时捕获plink失败

时间:2013-07-09 12:50:43

标签: powershell error-handling try-catch

我的一个脚本出了问题。基本上它运行非常流畅但它需要来自excel文件的一些用户输入。用户可能会导致错误,这就是我的问题。 我的脚本通过ssh与plink(lil PuTTY)连接到某些设备并发送命令。

现在到了真正的问题:如果有人错过了FQDN,脚本将继续,但我需要通过电子邮件报告一个进程失败。如果有人完全搞砸了Excel-Sheet,整个脚本将失败 - 我需要再次知道。我已经设计了一些参数来给我发电子邮件。唯一的问题是错误处理。

代码:

try {
  $FQDN | foreach {
    $directory = $dir[$counter]
    $errorzahl = $error.count + [int]1

    &$process -ssh -l $loginname[$counter] -pw $pw[$counter] $FQDN[$counter] "config global execute $cmd config ftp $filename $FTPADRESS $FTPLOGIN $FTPPW"
    $names = $KN[$counter]
    if ($error.Count -gt $errorzahl) {
      $names = $KN[$counter]
      $smtp.Send("$ErrorSender", "$ErrorRecipient", "Powershell Script Error",
                 "$Emailinhaltlow, Problems: $names")
    }
    $counter = $counter + [int]1
  } 

} catch {
  $errornachricht = $_.Exception.Message
  if ($_.Exception.Message) {
    $smtp.Send("$ErrorSender", "$ErrorRecipient", "Powershell Error",
               "$Emailinhalt, Probleme mit: $names")
    unregister-scheduledjob -Name $jobname -Force
  }
}

这不起作用。我收到了一个关于数组FQDN中每个字符串的电子邮件,如果excel表中只有一个错误,“try and catch”也会向我发送错误邮件,如果脚本完成其工作则不应该发生什么。 / p>

如果我删除此条件:

if ($error.Count -gt $errorzahl) {
  $names = $KN[$counter]
  $smtp.Send("$ErrorSender", "$ErrorRecipient", "Powershell Error",
             "$Emailinhaltlow, Problems: $names")
}

我没有收到任何电子邮件。即使foreach循环中存在一些小错误。

编辑错误代码(Powershelloutput为红色) 错误 - 如果有人忘记用ssh连接一次并接受证书一次 - !停止整个脚本!:

plink.exe : The server's host key is not cached in the registry. You
In C:\Users\USER\Desktop\VPNscript.ps1:10 Zeichen:1
+ &$process -ssh -l $loginname -pw $pw $FQDN "y
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (The server's ho...e registry. You:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError

have no guarantee that the server is the computer you
think it is.
The server's rsa2 key fingerprint is:
ssh-rsa 2048 c2:ea:62:af:70:14:e4:f0:a0:79:88:45:85:fc:cd:cc
If you trust this host, enter "y" to add the key to
PuTTY's cache and carry on connecting.
If you want to carry on connecting just once, without
adding the key to the cache, enter "n".
If you do not trust this host, press Return to abandon the
connection.
Store key in cache? (y/n) 

主要不是主题,但如果我已经上传错误,有人可能会修复错误,而不会选择新问题。这是其中之一。我无法将“y”发送到plink。

另一个错误 - 如果FQDN错误(不存在 - Excel表格中的拼写错误) - 脚本将继续,但在excelsheet中有一行失败:

plink.exe : Unable to open connection:
In Zeile:73 Zeichen:1
+ &$process -ssh -l $loginname[$counter] -pw $pw[$counter] $FQDN[$counter] "config ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (Unable to open connection::String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError

Host does not exist

编辑2:

"y" | &$process -ssh -l $Loginname -pw $pw $FQDN
plink.exe : The server's host key is not cached in the registry. You
In Zeile:6 Zeichen:7
+ "y" | &$process -ssh -l $Loginname -pw $pw $FQDN
+       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (The server's ho...e registry. You:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError

have no guarantee that the server is the computer you
think it is.
The server's rsa2 key fingerprint is:
ssh-rsa 2048 c2:ea:62:af:70:14:e4:f0:a0:79:88:45:85:fc:cd:cc
If you trust this host, enter "y" to add the key to
PuTTY's cache and carry on connecting.
If you want to carry on connecting just once, without
adding the key to the cache, enter "n".
If you do not trust this host, press Return to abandon the
connection.
Store key in cache? (y/n) 

3 个答案:

答案 0 :(得分:4)

plink失败不会抛出(PowerShell)错误,因此不会增加$error计数。如果要检测命令是成功还是失败,请检查$LastExitCode

对于某人“弄乱Excel表格”:在这种情况下脚本究竟是如何失败的?处理此错误将在很大程度上取决于实际错误。


主机密钥问题可以通过在命令中回显“y”来处理:

"y" | &$process -ssh -l $loginname[$counter] ...

或在运行命令之前将密钥写入注册表:

$key = "HKCU:\Software\SimonTatham\PuTTY\SshHostKeys"
$val = "0x23,0x3857aee9..."
Set-ItemProperty $key "rsa2@22:$($FQDN[$counter])" $val

&$process -ssh -l $loginname[$counter] ...

针对不存在的FQDN运行plink未在我的测试中引发终止错误:

PS C:\> $process = "plink.exe"
PS C:\> $fqdn = "correct.intern.example.org", "fail.intern.example.org"
PS C:\> nslookup $fqdn[1]
Server:  ns.intern.example.org
Address:  10.42.23.1

DNS request timed out.
    timeout was 2 seconds.
DNS request timed out.
    timeout was 2 seconds.
*** ns.intern.example.org can't find fail.intern.example.org: Non-existent domain
PS C:\> &$process -ssh -l username $fqdn[1] "echo foo"
Unable to open connection:
Host does not exist

即使我设置了$ErrorActionPreference = "stop"

但是,如果您收到终止错误,它也应该增加$error.Count。但是,您的检查不起作用,因为您记住以前的错误计数加上一个

$errorzahl = $error.Count + [int]1

然后检查新错误计数是否更大

if ($error.Count -gt $errorzahl) {
  ...

请改为尝试:

$errorzahl = $error.Count
...
if ($error.Count -gt $errorzahl) {
  ...

答案 1 :(得分:2)

您可能想要使用这样的函数(from psake):

function Exec
{
    [CmdletBinding()]
    param(
        [Parameter(Position=0,Mandatory=1)][scriptblock]$cmd,
        [Parameter(Position=1,Mandatory=0)][string]$errorMessage = ($msgs.error_bad_command -f $cmd)
    )
    & $cmd
    if ($lastexitcode -ne 0) {
        throw ("Exec: " + $errorMessage)
    }
}

现在您可以拨打以下外部程序:

Exec { external.exe } "Failed!"

答案 2 :(得分:1)

我认为4.0版本中的Powershell 2.0存在问题,返回错误。 要强制抛出错误,请将 2>& 1 附加到外部命令。

& $process -ssh -l username $fqdn "echo foo" 2>&1