0

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

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

代码:

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”也向我发送了错误邮件,如果脚本完成了它的工作,不应该发生什么。

如果我只是删除这个条件:

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

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

编辑错误代码(Powershell 输出为红色) 错误 - 如果有人忘记使用 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 错误(不存在 - Excelsheet 中的拼写错误) - 脚本将继续,但在 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) 
4

3 回答 3

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 ]
服务器:ns.intern.example.org
地址:10.42.23.1

DNS 请求超时。
    超时为 2 秒。
DNS 请求超时。
    超时为 2 秒。
*** ns.intern.example.org 找不到 fail.intern.example.org:不存在的域
PS C:\> &$process -ssh -l 用户名 $fqdn[1] "echo foo"
无法打开连接:
主机不存在

甚至当我设置$ErrorActionPreference = "stop".

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

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

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

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

试试这个:

$errorzahl = $error.Count
...
if ($error.Count -gt $errorzahl) {
  ...
于 2013-07-09T13:31:30.567 回答
2

您可能想要使用这样的函数(来自 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!"
于 2013-07-09T17:31:10.090 回答
1

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

& $process -ssh -l username $fqdn "echo foo" 2>&1
于 2014-07-16T16:42:03.650 回答