0

スクリプトの 1 つに問題があります。基本的には非常にスムーズに実行されますが、Excel ファイルからのユーザー入力が必要です。ユーザーはエラーを引き起こす可能性があり、それが私の問題です。plink私のスクリプトは、 (lil PuTTY) を使用して ssh 経由で特定のデバイスに接続し、コマンドを送信します。

本当の問題: 誰かが FQDN のスペルを間違えただけで、スクリプトは続行されますが、1 つのプロセスが失敗したことを電子メールで報告する必要があります。誰かが 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
  }
}

これは正常に機能しません。Excelシートにエラーが1つだけあり、「試してキャッチ」でもエラーメールが送信された場合、配列FQDN内のすべての文字列に対して電子メールを受け取ります。

この条件を削除すると、次のようになります。

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

メールが届きません。foreachループに小さなエラーがあっても。

EDIT ERRORCODES (赤の Powershelloutput) エラー - 誰かが ssh で 1 回接続し、証明書を 1 回受け入れるのを忘れた場合 - !スクリプト全体を停止します!:

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) 

主にトピックではありませんが、既にエラーをアップロードしている場合、誰かが新しい質問を開くことなくエラーを修正する可能性があります。これはそれらの1つです。「y」を plink に送信できません。

別のエラー - FQDN が間違っている場合 (存在しない - Excel シートのスペル エラー) - スクリプトは続行されますが、Excel シートの 1 行で失敗します。

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] ...

plink私のテストでは、存在しない FQDN に対して実行しても終了エラーは発生しませんでした。

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、同様にインクリメントする必要があります。ただし、前のエラー カウント+ 1を覚えているため、チェックは機能しません。

$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 に答える