Windowsタスクスケジューラで自動化を回すときの実務メモ

Windowsタスクスケジューラで自動処理を回していて、実際につまずいた点をまとめます。戻り値267009・267014の意味、PowerShellのSet-ScheduledTaskでハマるTaskPath、そして「戻り値0なのに何もしていなかった」という失敗の話です。

戻り値はエラーコードとは限らない

タスクスケジューラの「前回の実行結果」に見慣れない数字が並んでいると、まずエラーを疑いたくなります。ですが、そもそも失敗を意味していないコードがあります。

267009 は「まだ実行中」

戻り値 267009SCHED_S_TASK_RUNNING です。これはタスクがまだ実行中であることを示すもので、エラーではありません。

実行結果の欄を見に行くタイミングが、タスクの動作中と重なっただけ、というケースがあります。監視スクリプトで実行結果を拾って「0以外なら異常」と判定していると、正常に動いている最中のタスクを異常として通報してしまいます

注意

戻り値を機械的に「0か、それ以外か」で判定する監視は、267009 を誤検知します。判定ロジックを書くときは、実行中を示すコードを除外対象として明示的に扱う必要があります。

267014 は「時間切れで強制終了」

戻り値 267014SCHED_S_TASK_TERMINATED です。これは実行時間の上限に達して、タスクが強制終了された状態を示します。

ここが厄介なのは、スクリプト側の視点では「途中で切られた」だけなので、スクリプトが自前で出力する終了ログが残らないことがある点です。処理が半分だけ終わった状態でプロセスが消えるので、中途半端なデータが残る可能性もあります。267014 を見つけたら、スクリプトのログではなくデータの側を確認しに行くほうが確実です。

戻り値 名前 意味
267009 SCHED_S_TASK_RUNNING まだ実行中。エラーではない
267014 SCHED_S_TASK_TERMINATED 実行時間の上限に達して強制終了された

PowerShellから設定を変えるときのTaskPath

タスクの設定をPowerShellから変更しようとして、最初に引っかかったのがこれです。Set-ScheduledTask は、タスクの置き場所(TaskPath)を指定しないとタスクを見つけられません

タスク名だけを渡しても、目的のタスクにたどり着かないことがあります。GUIのタスクスケジューラでは左側のツリーでフォルダを掘って表示しているので、「どのフォルダに置いたか」を普段あまり意識しません。そのため、名前は合っているのに見つからない、という状態になって混乱します。

ポイント

タスクを自作フォルダに整理して置いている場合、PowerShellから操作するときは TaskPath を必ずセットで扱います。「名前で引けないときはパスを疑う」を先に覚えておくと、原因調査の時間を丸ごと節約できます。

いちばん怖いのは「成功しているのに何もしていない」

ここからが本題です。戻り値の読み方より、実務でダメージが大きかったのはこちらでした。

戻り値0は「起動して終了した」以上のことを保証しない

実行結果が0でも、処理件数が0件ということがあります。スクリプトが起動して、エラーを出さずに最後まで走り、正常終了した。タスクスケジューラから見えるのはそこまでです。その中で実際に何件処理したのかは、戻り値には一切現れません。

つまり、戻り値だけを見て「動いている」と判断すると、失敗に気づけません。動いてはいるのです。ただ、仕事をしていないだけです。

失敗したこと

戻り値0のまま、3日連続で処理件数が0でした。ログに件数を数字で書いていなかったため、まったく気づけませんでした。実行結果の一覧はきれいに0が並んでいて、見た目上はむしろ「順調」でした。

実測

3日 連続で処理0件
戻り値はすべて0。件数をログに残していなかったため発覚が遅れた

対策は「件数を数字でログに書く」だけ

この件から得た結論は単純です。ログに処理件数を数字で残す。これに尽きます。

「正常終了しました」というログは、この失敗をまったく防げませんでした。実際に正常終了していたからです。防げるのは、次のように件数そのものが目に入る形のログです。

処理件数: 0
処理件数: 0
処理件数: 0

0が3行並んでいれば、さすがに気づきます。逆に言えば、数字が書かれていないログは、この種の異常に対しては無いのと同じでした。

  • 件数を数字でログに出す
  • 戻り値0=処理成功、と読み替えない
  • 267009 を異常扱いしない判定にする
  • 「正常終了」の文字だけのログでは、0件稼働を検知できなかった
  • タスクスケジューラの実行結果一覧を眺めるだけでは、3日間気づけなかった

まだ分かっていないこと

正直に書いておくと、あのときなぜ3日間も処理対象が0件だったのか、根本原因はまだ特定できていません。件数ログを入れたのは発覚後なので、その3日間について後から追える材料が残っていないためです。

また、267014 で強制終了された場合に処理がどこまで進んでいたのかも、スクリプト側のログ設計次第で追えたり追えなかったりします。ここも自分の環境では詰め切れていません。「戻り値を見れば状態が分かる」というのは、思っていたより成り立たない前提でした。

うまくいったこと

件数を数字でログに残すようにしてからは、実行結果ではなくログの数字を見る運用に切り替わりました。監視対象が「タスクが動いたか」から「何件処理したか」に変わったのが、いちばん大きい変化です。

まとめ

  • 267009 は SCHED_S_TASK_RUNNING、まだ実行中という意味でエラーではない
  • 267014 は SCHED_S_TASK_TERMINATED、実行時間の上限に達して強制終了された状態
  • PowerShell の Set-ScheduledTask は TaskPath を指定しないとタスクを見つけられない
  • 実行結果0でも処理0件はあり得る。戻り値だけで「動いている」と判断すると失敗に気づけない
  • 実際に戻り値0のまま3日連続で0件だった。件数を数字でログに書いていなかったのが原因で発覚が遅れた
  • その3日間の根本原因は、記録が無いため今も特定できていない