2013-01-09 4 views
8

最近私が考えていたことがありました。PowerShellスクリプトでエラーが発生した場合に電子メールを送信し、スクリプトを終了させて​​ください。

(タスクスケジューラを使用して)さまざまなスケジュールで非常に多くのPowerShellスクリプトを実行しています。これらのスクリプトは一般にデータを収集し、私のためにSQLテーブルに格納します。私は40-50のスクリプトを実行していると思います。エラーが発生した場合、スクリプトは、さらに処理せずに終了することを保証する

  1. :私は真剣に最近検討されている

    ことの一つは、最良の方法です。

  2. このスクリプトでは、例外の詳細が表示されない場合はメールを送信し、どれくらいの距離であるかを表示する必要があります。
  3. 記録/進捗状況がログに記録されますので、エラーを確認してスクリプトで処理することをお勧めします。

これはかなりの作業であるため、最初から適切なアプローチを取りたいと思います。私はこのような何かを達成するための見ることができる唯一の方法は、次の操作を行うことであろう

セット$ ErrorActionPreferenceこれは、すべての例外は、のtry/catchをトリガーするようになります

を「停止」にしますブロック。

Try/Catch/Finallyブロック内でスクリプト全体を実行します。

最後にブロックはもちろんオプションです。このような何か:

$ErrorActionPreference = "Stop" 

Try 
{ 
    $Content = gc "C:\Temp\NonExistentFile.txt" 
    foreach ($Line in $Content) 
    { 
     Write-Host $Line 
    } 
} 
Catch 
{ 
    Write-Host $_ -ForegroundColor "Red" -BackgroundColor "Black" 
    break 
} 

HTMLの中に「トランスクリプト」のデータをログに記録し、失敗した場合にコンテンツを電子メールで送信します。

私はログのいくつかの方法を試してみた、と私のためのキーのものの一つは、私が何かをしたいということです。

  1. にログインするための簡単なテキスト、およびログファイルを提供することにより、ロケーション。
  2. ログファイルの各行の先頭に日付/時刻を含めます。

テキストを.txtファイルに書き出し始めましたが、それはやるべきことでした。

Start-TranscriptはOKでしたが、各行に日付/時刻は含まれていませんでした。

私は、Start-Transcriptを使用するカスタム関数でいくつかの成功を収め、Write-Hostに送信したテキストを各行の開始時に日付/時刻とともに書き込みます。

最終的に私は、.html文書にログインし、エラーが発生した場合には、この内容を電子メールで送信する必要があると思います。例のようなもの:

Function Send-ErrorEmail 
{ 
    Write-Host "Would Send Email Here" -ForegroundColor "Magenta" 
} 

Function Write-Html 
{ 
    [CmdletBinding()] 
    param 
    (
     [Parameter(ValueFromPipeline=$True)]$Text, 
     $HTMLTag 
    ) 

    [string]$CurrentDateTime = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss - ") 

    switch ($HTMLTag) 
    { 
     "h1" {$ReturnText = ("<h1>" + $Text + "</h1>")} 
     "h2" {$ReturnText = ("<h2>" + $Text + "</h2>")} 
     default {$ReturnText = ("<p>" + $CurrentDateTime + $Text + "</p>")} 
    } 

    Write-Host -ForegroundColor "Yellow" ($CurrentDateTime + $Text) 
    return $ReturnText 
} 

$ErrorActionPreference = "Stop" 

Try 
{ 
    #Stores the HTML File 
    $LogfilePath = "C:\Temp\LogFile.html" 

    #Begin HTML 
    $HTML = @() 
    $HTML += "<html><head></head><body>" 
    $HTML += "Begin Script" | Write-Html 

    #Loop through Computers 
    $Computers = "LocalHost", "DoesNotExist", "127.0.0.1" 
    foreach ($Computer in $Computers) 
    { 
     #Get Services 
     $HTML += "Computer: $Computer" | Write-Html -HTMLTag "h1" 
     $Services = Get-Service -Computer $Computer 
     $HTML += $Services | ConvertTo-Html -Fragment 
    } 

    #Complete HTML 
    $HTML += "Script End" | Write-Html 
    $HTML += "</body></html>" 
    $HTML | Out-File $LogfilePath 
} 
Catch 
{ 
    #Add Exception to HTML 
    $HTML += $_ | Out-String | Write-Html 

    #Complete HTML 
    $HTML += "</body></html>" 
    $HTML | Out-File $LogfilePath 

    #Send EMail 
    Send-ErrorEmail 

    #Exit Script 
    exit 
} 

どのような考えですか?私ができると思う改善?明らかにHTML書類はCSS書式がないと醜いですし、Send Mail機能は何もしませんが、私がしたいことをする最も簡単な方法と思われます。

通知電子メールアドレスなどの変更を容易にするために、すべてのスクリプトの間で任意の機能を使用できます。

+0

あなたの質問のタイトルを質問に変更することをお勧めします。それは主題を表すために変更することをお勧めします。 –

答えて

10

グローバルなエラー処理については、トラップ文を使用することをお勧めします。

function ErrorHandler($error) 
{ 
    ... write out error info 
    ... send email message with error info 
    ... etc 
} 

trap { ErrorHandler $_; break } 

... rest of script code 

そして、あなたはどんなエラーで救済したい場合は、[はい、Stop$ErrorActionPreferenceを設定します。

+2

興味深いことに、私はトラップステートメントをもう少し読んでいて、これを見て、それがあなたのことだと分かった! :) http://rkeithhill.wordpress.com/2009/08/03/effective-powershell-item-16-dealing-with-errors/ - 私はそれに多くの時間を費やしていないが、それはトラップのように見えるインタラクティブに呼び出されたときにステートメントが正しく動作しない.ps1ファイルに入れて実行しない限り、トラップを呼び出す最後の例は2番目にはありません。 – HungryHippos

+0

私は通常、対話的にトラップを使用しませんが、グローバルなスコープ以外のスコープを入れて動作させることができます。対話形式でこれを実行してください: '&{trap {"トラップされたエラー!! ";持続する };投げて "oops"} ' –

+0

キース、ありがとう、私はちょうど私がトラップ{}を代わりに使用できるようにスクリプトを少しテストした方法を変更しました。試してみるか、キャッチするかのように、スクリプトの中で一度宣言する方が良いと思う。インタラクティブにスクリプトをテストすることについて私が見逃している主なことは、間隔でフィールド/データの変数を検査することです。私はあなたの応答を答えとしてマークします。 – HungryHippos

関連する問題