TL;DR
0x1 = タスクのプログラムがゼロ以外の終了コードで終了した(汎用的な失敗)。0x41301 = タスクが現在実行中、または前回の実行からハングしている。確認チェックリスト:
- まずCMDでコマンドを手動実行する。そこで失敗するなら、スケジューラではなくコマンドを修正する。
- **「開始」**をスクリプトが存在するフォルダに設定する。
- **「ユーザーがログオンしているかどうかにかかわらず実行する」と「最上位の特権で実行する」**を確認する。
- 0x41301の場合:ハングしているインスタンスを強制終了し、停止タイムアウトを設定する。
これらのコードが実際に意味すること
タスクスケジューラ自体が0x1を生成するわけではありません。プログラムが返した終了コードをそのまま転送しているだけです。終了コード1は、あらゆる言語で「何かが壊れた」を示す汎用シグナルです。Pythonもそれを使います。Bashも使います。バッチスクリプトでさえデフォルトでそれを使います。だからこそ0x1は何も具体的なことを教えてくれません。プログラム自体を確認する必要があります。
0x41301は別物です。これはタスクスケジューラの内部コードで、タスクがすでに実行中であることを意味します。前のインスタンスが次のトリガーが発火する前に終了しなかった場合に発生します。例えば、90分かかるバックアップジョブが1時間ごとに実行されるケースです。
ステップ1 — 手動で失敗を再現する
タスクスケジューラの設定を触る前に、タスクが実行するのと同じユーザーでCMDを開き、まったく同じコマンドを実行します。十中八九、エラーはそこで確認できます。
# タスクがPowerShellスクリプトを実行する場合:
powershell.exe -ExecutionPolicy Bypass -File "C:\Scripts\backup.ps1"
# 直後に終了コードを確認:
echo %ERRORLEVEL%
ERRORLEVELがゼロ以外?スクリプトが壊れています。まずスクリプトを修正してください。スケジューラは単なる使者にすぎません。
ステップ2 — 「開始」ディレクトリを修正する
この一つの設定が0x1ケースの約40%を占めます。相対パス(./config.json、../logs/)を使用するスクリプトは、タスクスケジューラがC:\Windows\System32から起動すると無警告で失敗します。
タスクスケジューラ → タスクを右クリック → プロパティ → 操作タブ → 操作を編集:
- プログラム/スクリプト:
powershell.exe(またはexeのフルパス) - 引数の追加:
-ExecutionPolicy Bypass -File "C:\Scripts\backup.ps1" - 開始(オプション):
C:\Scripts← スクリプトのディレクトリを指定する
ステップ3 — 権限とユーザーコンテキストを修正する
「ユーザーがログオンしているときのみ実行する」タスクはデスクトップセッションを継承します。バックグラウンドで実行すると、デスクトップなし・アクセス制限付きの縮小トークンが割り当てられます。修正すべき点:
- 全般タブ → **「ユーザーがログオンしているかどうかにかかわらず実行する」**を選択する
- タスクに管理者権限が必要な場合は**「最上位の特権で実行する」**を確認する
- プロンプトが表示されたら資格情報を入力する。タスクスケジューラが暗号化して保存します
もう一つの落とし穴:タスクがネットワーク共有にアクセスする場合、SYSTEMとして実行しないでください。SYSTEMアカウントにはネットワーク資格情報がありません。それらのパスに実際にアクセスできるドメインサービスアカウントを使用してください。
ステップ4 — ログを有効にして実際のエラーを確認する
出力をログファイルにリダイレクトします。これがなければ推測するしかありません。
<!-- タスクの操作 → 引数に追加: -->
-ExecutionPolicy Bypass -File "C:\Scripts\backup.ps1" >> "C:\Logs\backup.log" 2>&1
<!-- またはcmd.exeでラップしてリダイレクトをわかりやすくする: -->
cmd.exe /c "powershell.exe -File C:\Scripts\backup.ps1 >> C:\Logs\backup.log 2>&1"
イベントビューアでタスクスケジューラの操作ログも有効にしてください。デフォルトではオフになっています:
# アプリケーションとサービス ログ → Microsoft → Windows → TaskScheduler → Operational
# 右クリック → ログを有効にする
# またはPowerShellで1行で実行:
wevtutil set-log Microsoft-Windows-TaskScheduler/Operational /enabled:true
次回の実行後、イベントID 201(完了)または203/101(理由付きの失敗)を確認します。特にイベント101では実際のエラーメッセージが表示されます。
0x41301の修正 — ハングしたインスタンス
前の実行がスタックしています。それを強制終了し、再び積み重ならないようにガードレールを設定します。
# 実行中のタスクインスタンスを検索:
Get-ScheduledTask | Where-Object {$_.State -eq 'Running'}
# 特定のタスクを停止:
Stop-ScheduledTask -TaskName "YourTaskName" -TaskPath "\YourFolder\"
# またはschtasksで:
schtasks /end /tn "\YourFolder\YourTaskName"
次にタスクのプロパティ → 設定タブを開きます:
- 「タスクが既に実行中の場合...」 → **「既存のインスタンスを停止する」または「新しいインスタンスを開始しない」**に設定する
- 「タスクの実行時間が次の時間を超えた場合は停止する」 → ハードタイムアウトを設定する。ほとんどのジョブでは1〜2時間で十分です。
PowerShellスクリプト — 終了コードが重要
明示的なexitなしで終了するPowerShellスクリプトは、最後のコマンドのステータスコードを返します。その最後のコマンドが失敗した場合(ロックされたファイルにヒットしたWrite-Hostでさえも)、0x1が返されます。明示的に記述してください:
try {
# ... 処理内容 ...
Write-Host "Done"
exit 0
} catch {
Write-Error $_.Exception.Message
exit 1 # 意図的な失敗
}
実行ポリシーも確認してください。PowerShellは有用な情報を何も表示せずにスクリプトを無警告でブロックすることがあります:
# 各スコープでの設定を確認:
Get-ExecutionPolicy -List
# タスクの操作では常に -ExecutionPolicy Bypass を渡す:
powershell.exe -ExecutionPolicy Bypass -NonInteractive -File "C:\Scripts\run.ps1"
schtasksによるクイック診断
# マシン上のすべてのタスクの最終実行結果:
schtasks /query /fo LIST /v | findstr /i "last run result"
# 特定のタスクを詳しく確認:
schtasks /query /tn "\MyFolder\MyTask" /fo LIST /v
# テスト用に今すぐトリガー:
schtasks /run /tn "\MyFolder\MyTask"
修正の確認
- タスクを右クリック → 実行
- タスクスケジューラを更新する。前回の実行結果が
0x0と表示されるはずです - ログファイルを開いて実際の出力を確認する
- イベントビューア → TaskScheduler/Operational → イベントID 201、結果0
# PowerShellでクイック確認:
(Get-ScheduledTaskInfo -TaskName "YourTaskName").LastTaskResult
# 返り値は 0 のはず
よくある原因の一覧
- 作業ディレクトリが間違っている — System32から起動すると相対パスが失敗する
- 権限が不足している — 管理者権限またはネットワークアクセスが必要だが持っていない
- スクリプトが壊れている — ゼロ以外で終了し、タスクスケジューラはそのまま報告するだけ
- 実行ポリシー — PowerShellがスクリプトを無警告でブロックする
- 前のインスタンスがハング(0x41301) — タイムアウトなしでインスタンスが積み重なる
- 依存関係が不足している — スクリプトがインストールされていないPython、Node、または他のツールを呼び出す

