【タスクスケジューラ】タスクのタイムアウトを検知し、メール通知を行うタスクを作成してみた

こんにちは、まなべです。 タスクスケジューラでスクリプトを起動させる際、無限ループ等により、タスクがタイムアウトしてしまうケースがあります。 今回は、タイムアウトを検知してメール通知を行うタスクの作成方法をご紹介します。
2023.12.05

① タイムアウトさせるタスクの作成

▼ スクリプトファイルの作成

以下の処理を行うスクリプトファイル「do-timeout.ps1」を作成します。

# 60秒間処理を停止させ、意図的にタイムアウトを発生させる
Start-Sleep -Seconds 60

▼ タスクの作成

デフォルト値を使用する設定項目は省略します。

① 「全般」タブの設定

項目名 設定値
名前 do-timeout-task

② 「トリガー」タブの設定

数分後に一度だけ起動するようにトリガーを作成します。

項目名 設定値
設定 1回
開始 ※数分後の時刻を設定

③ 「操作」タブの設定

項目名 設定値
プログラム/スクリプト C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
引数の追加 -c "C:\Users\Administrator\test\do-timeout.ps1"

④ 「設定」タブの設定

1秒でタイムアウトするように設定します。

項目名 設定値
タスクを停止するまでの時間 1秒間

▼ 動作確認

トリガーによるタスクの起動を待ちます。
※手動でタスクを実行した場合、先ほどのタイムアウト時間の設定は無視されタスクが正常終了してしまう(タスクスケジューラの仕様)ため、タイムアウトは発生しません。

タスク起動後、タスクの履歴・Windowsイベントログを確認します。

無事タイムアウトしたようです。

Windowsイベントログに出力されている以下の情報を控えておきます。

  • タイムアウトログの出力先パス:「Microsoft-Windows-TaskScheduler/Operational」
  • イベントID:「329」
  • イベント名:「StoppedOnTimeout」
  • タスク名:「\test\do-timeout-task」

② タイムアウトを検知するタスクの作成

▼ スクリプトファイルの作成

以下の処理を行うスクリプトファイル「send-timeout-mail.ps1」を作成します。
今回は SmtpClient を使用してメール通知機能を実装しました。

$From = "送信元メールアドレス"
$To = "送信先メールアドレス"
$Subject = "エラー通知テスト" 
$Body = "タイムアウトエラーが発生しました" 
$SMTPServer = "SMTPサーバ名" 
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587) 
$SMTPClient.EnableSsl = $true 
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("SMTPサーバーのユーザー名", "SMTPサーバーのパスワード"); 

$Mail=New-Object Net.Mail.MailMessage($From,$To,$Subject,$Body)
$SMTPClient.Send($Mail)

▼ タスクの作成

デフォルト値を使用する設定項目の説明は割愛します。

① 「全般」タブの設定

項目名 設定値
名前 send-timeout-mail-task

② 「トリガー」タブの設定

以下のように基本設定からトリガーを作成することもできますが、これでは「Microsoft-Windows-TaskScheduler/Operational」に出力された「do-timeout-task」以外のタイムアウトログも検知してしまうため、今回はカスタム設定でトリガーを作成します。

項目名 設定値
タスクの開始 イベント時
設定 カスタム

イベントフィルターを以下のXMLで定義します。
「do-timeout-task」のタイムアウト時のイベントログ確認時に控えた情報を記載しています。

<QueryList>
  <Query Id="0" Path="Microsoft-Windows-TaskScheduler/Operational">
    <Select Path="Microsoft-Windows-TaskScheduler/Operational">
      *[System[(EventID=329)]] and Event[EventData[@Name="StoppedOnTimeout"][Data[@Name="TaskName"]="\do-timeout-task"]]
    </Select>
  </Query>
</QueryList>

③ 「操作」タブの設定

項目名 設定値
プログラム/スクリプト C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
引数の追加 -c "C:\Users\Administrator\test\send-timeout-mail.ps1"

③ 動作確認

再度、数分後に「do-timeout-task」が起動するようにトリガーを設定し、起動を待ちます。 タイムアウトが発生し、無事メールが届きました!