バッチファイルでシステムのメンテナンスや定期処理を自動化するとき、タスクスケジューラへの登録作業が毎回手作業では効率が悪くなります。schtasksコマンドを使えば、バッチスクリプト自身がタスクの登録・更新・削除まで自動的に完結できます。
本記事では単なるコマンド解説にとどまらず、現場で実際に使えるパターンに焦点を当てます。「登録済みなら更新、未登録なら新規登録」という条件分岐、バッチファイルが自分自身をタスクに登録する自己登録パターン、管理者権限なしで動かすSYSTEM実行、エラーログの自動保存まで、実務で必要な知識をまとめます。
- schtasksで登録・更新・削除を行うコマンドの基本構文
- 登録済みかどうか確認してから登録・更新を切り替えるパターン
- バッチファイルが自分自身をタスクスケジューラに登録する自己登録パターン
- 管理者権限なし・パスワードなし・SYSTEM実行などの権限設定
- 実行ログ・エラーログをファイルに残す方法
- 削除確認なし(/F)での安全な一括削除
schtasksコマンドの基本構文早見表
まず各サブコマンドの役割を整理します。
| サブコマンド | 役割 | 主なオプション |
|---|---|---|
schtasks /create |
タスクを新規登録 | /TN(名前)/TR(実行コマンド)/SC(頻度)/ST(時刻) |
schtasks /query |
登録済みタスクを一覧・確認 | /TN(タスク名)/FO LIST /V |
schtasks /run |
タスクを手動で即時実行 | /TN(タスク名) |
schtasks /change |
タスクのコマンド・スケジュールを変更 | /TN /TR /SC /ST |
schtasks /end |
実行中のタスクを停止 | /TN(タスク名) |
schtasks /delete |
タスクを削除 | /TN /F(確認なし) |
タスクの新規登録(/create)
基本的な毎日実行の登録
最も頻繁に使うパターンから確認します。/SC DAILYで毎日、/STで開始時刻を指定します。
@echo off
schtasks /create ^
/TN "MyBackupJob" ^
/TR "cmd /c cd /d C:\Scripts && backup.bat >> C:\logs\backup.log 2>&1" ^
/SC DAILY ^
/ST 02:00 ^
/RL HIGHEST ^
/F
if %ERRORLEVEL% equ 0 (
echo [OK] タスクの登録が完了しました
) else (
echo [ERROR] タスクの登録に失敗しました (ERRORLEVEL=%ERRORLEVEL%)
exit /b 1
)
/Fなしでは「上書きしますか?」と確認ダイアログが出て処理が止まります。バッチで自動実行する場合は必ず/Fを付けて無確認上書きにします。スケジュール頻度の一覧
| /SC 値 | 頻度 | 追加オプション例 |
|---|---|---|
ONCE |
1回だけ実行 | /SD 2026/04/01 /ST 09:00 |
DAILY |
毎日 | /ST 02:00(時刻指定) |
WEEKLY |
毎週 | /D MON(曜日指定)/ST 09:00 |
MONTHLY |
毎月 | /D 1(日付指定)/ST 09:00 |
ONLOGON |
ログオン時 | (時刻不要) |
ONSTART |
システム起動時 | (時刻不要、管理者権限必要) |
ONIDLE |
アイドル時 | /I 分数(アイドル継続時間) |
ONEVENT |
イベントログのイベント発生時 | /EC System /MO <QueryXML> |
schtasks /create /TN "WeeklyCleanup" /TR "C:\Scripts\cleanup.bat" /SC WEEKLY /D MON /ST 09:00 /RL HIGHEST /F
schtasks /create /TN "MonthlyReport" /TR "C:\Scripts\report.bat" /SC MONTHLY /D 1 /ST 03:30 /RL HIGHEST /F
権限設定(/RL と /RU の使い分け)
| 設定 | 意味 | 用途 |
|---|---|---|
/RL HIGHEST |
管理者権限(最高レベル)で実行 | レジストリ操作・サービス管理など権限が必要な処理 |
/RL LIMITED |
通常ユーザー権限で実行(デフォルト) | ファイル操作など一般的な処理 |
/RU SYSTEM |
SYSTEMアカウントで実行 | ログオン不要・パスワード不要で常時実行したいとき |
/RU ユーザー名 /RP パスワード |
指定ユーザーで実行 | 特定ユーザーのネットワーク接続が必要なとき |
/RU SYSTEMを指定するとSYSTEMアカウントで実行されます。パスワード入力不要で、ログオフ中でも実行できます。ただしSYSTEMアカウントはネットワークドライブにアクセスできないため、ネットワーク共有が必要な処理には不向きです。schtasks /create ^
/TN "SystemMaintenance" ^
/TR "cmd /c cd /d C:\Scripts && maintenance.bat" ^
/SC DAILY ^
/ST 03:00 ^
/RU SYSTEM ^
/F
登録済み確認→未登録なら登録、登録済みなら更新パターン
タスクを登録するスクリプトを繰り返し実行する場合、「初回は登録、2回目以降は更新」という制御が必要になることがよくあります。schtasks /queryのERRORLEVELで判断できます。
@echo off
set "TASK_NAME=MyDailyJob"
set "TASK_CMD=cmd /c cd /d C:\Scripts && job.bat >> C:\logs\job.log 2>&1"
set "TASK_TIME=02:00"
rem タスクが既に登録されているか確認
schtasks /query /TN "%TASK_NAME%" >nul 2>&1
if %ERRORLEVEL% equ 0 (
echo [INFO] 既存タスクを更新します: %TASK_NAME%
schtasks /change /TN "%TASK_NAME%" /TR "%TASK_CMD%" /ST "%TASK_TIME%"
) else (
echo [INFO] タスクを新規登録します: %TASK_NAME%
schtasks /create /TN "%TASK_NAME%" /TR "%TASK_CMD%" /SC DAILY /ST "%TASK_TIME%" /RL HIGHEST /RU SYSTEM /F
)
if %ERRORLEVEL% equ 0 (
echo [OK] 完了しました
) else (
echo [ERROR] 失敗しました (ERRORLEVEL=%ERRORLEVEL%)
exit /b 1
)
/create /Fだけでも既存タスクを上書きできますが、/Fは登録時のオプションをすべて上書きするため、スケジュールの変更なしにコマンドだけ変えたいときは/changeを使う方が安全です。バッチファイルが自分自身を登録する自己登録パターン
デプロイ・セットアップスクリプトでよく使うパターンです。バッチファイルを1回実行するだけで、以降は自動的にスケジュール実行されるように自分自身をタスクに登録します。
@echo off
setlocal
rem このスクリプト自身のフルパスを取得
set "SELF=%~f0"
set "SELF_DIR=%~dp0"
set "TASK_NAME=SelfRegisteredJob"
rem 管理者権限チェック
net session >nul 2>&1
if %ERRORLEVEL% neq 0 (
echo [ERROR] このスクリプトは管理者として実行してください。
echo 右クリック → 管理者として実行 で再起動してください。
pause
exit /b 1
)
rem 既存タスクの確認
schtasks /query /TN "%TASK_NAME%" >nul 2>&1
if %ERRORLEVEL% equ 0 (
echo [INFO] タスク "%TASK_NAME%" は登録済みです。更新します。
schtasks /change /TN "%TASK_NAME%" /TR "cmd /c cd /d "%SELF_DIR%" && "%SELF%""
) else (
echo [INFO] タスク "%TASK_NAME%" を新規登録します。
schtasks /create ^
/TN "%TASK_NAME%" ^
/TR "cmd /c cd /d "%SELF_DIR%" && "%SELF%" >> "%SELF_DIR%job.log" 2>&1" ^
/SC DAILY ^
/ST 03:00 ^
/RU SYSTEM ^
/F
)
if %ERRORLEVEL% equ 0 (
echo [OK] タスクスケジューラへの登録が完了しました。
echo 登録タスク: %TASK_NAME%
echo 実行ファイル: %SELF%
echo 実行時刻: 毎日 03:00
) else (
echo [ERROR] 登録に失敗しました。
exit /b 1
)
rem ここ以降が実際の処理(スケジュール実行時もここから動く)
:MAIN_PROCESS
rem ... 実際の処理 ...
echo 処理を実行しました: %DATE% %TIME%
:MAIN_PROCESSに続いて実行されてしまいます。登録時と実行時で処理を分けたい場合は、引数で制御します(例: %~nx0 --runで通常実行、引数なしで登録モード)。作業ディレクトリの問題と解決策
タスクスケジューラから実行されるバッチファイルは、作業ディレクトリがSystem32になるという罠があります。cdでパスを移動しようとしても、バッチ内の相対パス参照がすべてSystem32基準になってしまいます。
rem タスクスケジューラから実行したとき cd work_dir rem System32\work_dir を参照してしまう type data.csv rem System32\data.csv を探してしまう
rem /TR に作業ディレクトリを cd /d で明示する
schtasks /create ^
/TN "MyJob" ^
/TR "cmd /c cd /d C:\Scripts && run.bat >> C:\logs\run.log 2>&1" ^
/SC DAILY /ST 02:00 /RU SYSTEM /F
詳しい原因と解決策はバッチファイルをタスクスケジューラで実行するとき動作が異なる原因と解決ガイドで解説しています。
タスクの確認・手動実行・停止
登録内容の確認(/query)
@echo off rem タスク名を指定して詳細表示 schtasks /query /TN "MyBackupJob" /FO LIST /V rem 全タスクをCSV形式でファイルに保存 schtasks /query /FO CSV > C:\logs\tasks_list.csv
タスク名: \MyBackupJob 次回実行時刻: 2026/03/22 2:00:00 最終実行時刻: 2026/03/21 2:00:05 最後の結果: 0 スケジュール: スケジュール データはこの形式では利用できません。 状態: 準備完了
手動実行と停止
@echo off rem 今すぐ実行 schtasks /run /TN "MyBackupJob" rem 実行中のタスクを停止 schtasks /end /TN "MyBackupJob"
タスクの更新(/change)
既存タスクのコマンドや実行時刻だけを変更したい場合は/changeを使います。/create /Fでの上書きと異なり、変更したい項目だけ指定できます。
@echo off rem 実行コマンドだけ変更 schtasks /change /TN "MyBackupJob" /TR "cmd /c cd /d C:\NewScripts && newjob.bat" rem 実行時刻だけ変更(04:30に変更) schtasks /change /TN "MyBackupJob" /ST 04:30 rem タスクを有効化・無効化 schtasks /change /TN "MyBackupJob" /ENABLE schtasks /change /TN "MyBackupJob" /DISABLE
タスクの削除(/delete)
/deleteに/Fを付けると確認なしで削除できます。複数タスクを一括削除する場合は/TN *でフォルダ内全タスクを対象にできます。
@echo off
set "TASK_NAME=MyBackupJob"
rem 削除前に存在確認
schtasks /query /TN "%TASK_NAME%" >nul 2>&1
if %ERRORLEVEL% neq 0 (
echo [INFO] タスク "%TASK_NAME%" は登録されていません
exit /b 0
)
rem 確認なしで削除
schtasks /delete /TN "%TASK_NAME%" /F
if %ERRORLEVEL% equ 0 (
echo [OK] タスク "%TASK_NAME%" を削除しました
) else (
echo [ERROR] 削除に失敗しました
exit /b 1
)
@echo off rem "\MyFolder\" 配下のタスクをすべて削除 schtasks /delete /TN "\MyFolder\*" /F rem 全タスク削除(非常に危険 - 本番環境では使用しないこと) rem schtasks /delete /TN * /F
実行ログ・エラーログをファイルに残す
タスクスケジューラから実行されるバッチは、コンソール出力を誰も見ていないため、必ずログファイルに残す仕組みを入れておきます。
@echo off
set "TASK_NAME=LoggedDailyJob"
set "SCRIPT_DIR=C:\Scripts"
set "LOG_DIR=C:\logs"
set "LOG_FILE=%LOG_DIR%\daily_job.log"
if not exist "%LOG_DIR%" mkdir "%LOG_DIR%"
schtasks /create ^
/TN "%TASK_NAME%" ^
/TR "cmd /c cd /d %SCRIPT_DIR% && job.bat >> %LOG_FILE% 2>&1" ^
/SC DAILY ^
/ST 02:00 ^
/RU SYSTEM ^
/F
実務テンプレート:インストーラー型バッチ(登録・確認・削除を1本で管理)
登録・確認・削除を引数で切り替えられるインストーラー型バッチです。デプロイ作業の標準パターンとして使えます。
@echo off
setlocal
set "TASK_NAME=DailyMaintenance"
set "TASK_CMD=cmd /c cd /d C:\Scripts && maintenance.bat >> C:\logs\maintenance.log 2>&1"
set "TASK_TIME=03:00"
rem 引数チェック
if "%~1"=="install" goto :INSTALL
if "%~1"=="uninstall" goto :UNINSTALL
if "%~1"=="status" goto :STATUS
if "%~1"=="run" goto :RUN
echo 使い方:
echo %~nx0 install タスクを登録する
echo %~nx0 uninstall タスクを削除する
echo %~nx0 status 登録状態を確認する
echo %~nx0 run 今すぐ手動実行する
exit /b 0
:INSTALL
echo [INSTALL] タスク "%TASK_NAME%" を登録します...
schtasks /create /TN "%TASK_NAME%" /TR "%TASK_CMD%" /SC DAILY /ST %TASK_TIME% /RU SYSTEM /F
if %ERRORLEVEL% equ 0 (
echo [OK] 登録完了: 毎日 %TASK_TIME% に実行されます
) else (
echo [ERROR] 登録失敗
exit /b 1
)
exit /b 0
:UNINSTALL
echo [UNINSTALL] タスク "%TASK_NAME%" を削除します...
schtasks /query /TN "%TASK_NAME%" >nul 2>&1
if %ERRORLEVEL% neq 0 (
echo [INFO] タスクは登録されていません
exit /b 0
)
schtasks /delete /TN "%TASK_NAME%" /F
if %ERRORLEVEL% equ 0 (
echo [OK] 削除しました
) else (
echo [ERROR] 削除失敗
exit /b 1
)
exit /b 0
:STATUS
schtasks /query /TN "%TASK_NAME%" >nul 2>&1
if %ERRORLEVEL% equ 0 (
echo [STATUS] 登録済み
schtasks /query /TN "%TASK_NAME%" /FO LIST /V
) else (
echo [STATUS] 未登録
)
exit /b 0
:RUN
echo [RUN] タスクを手動実行します...
schtasks /run /TN "%TASK_NAME%"
exit /b %ERRORLEVEL%
rem 初回インストール >task_manager.bat install [INSTALL] タスク "DailyMaintenance" を登録します... [OK] 登録完了: 毎日 03:00 に実行されます rem 状態確認 >task_manager.bat status [STATUS] 登録済み タスク名: \DailyMaintenance 次回実行時刻: 2026/03/22 3:00:00 状態: 準備完了 rem アンインストール >task_manager.bat uninstall [UNINSTALL] タスク "DailyMaintenance" を削除します... [OK] 削除しました
よくある落とし穴と対処法
落とし穴①:タスク名やパスにスペースが含まれているとエラーになる
rem エラーになる schtasks /create /TN MyJob /TR C:\My Scripts\run.bat /SC DAILY /ST 02:00
rem 正常に動作する schtasks /create /TN "My Job" /TR "C:\My Scripts\run.bat" /SC DAILY /ST 02:00 /F
落とし穴②:管理者権限なしで /RL HIGHEST が使えない
/RL HIGHEST(最高権限)でのタスク登録は、schtasksコマンド自体を管理者権限で実行する必要があります。権限不足の場合はエラーコード1が返ります。
net session >nul 2>&1のERRORLEVELが0なら管理者権限あり、1なら管理者権限なしです。権限なしで実行すると/RL HIGHESTの指定は無視される場合があります。落とし穴③:SYSTEMアカウントではネットワークドライブが使えない
/RU SYSTEMはログオン不要で便利ですが、SYSTEMアカウントはネットワーク認証を持たないため、\\サーバー\共有フォルダへのアクセスができません。ネットワークドライブが必要な処理は専用のユーザーアカウントを/RUで指定してください。
落とし穴④:/TR内の特殊文字のエスケープ
/TR内で&(コマンド連結)や>(リダイレクト)を使う場合、コマンドプロンプトが先に解釈してしまうのでキャレット(^)でエスケープします。
rem エラー: & が先に解釈される schtasks /create /TN "Job" /TR "cd C:\Scripts & run.bat" /SC DAILY /ST 02:00
rem ^ でエスケープ schtasks /create /TN "Job" /TR "cd /d C:\Scripts ^& run.bat" /SC DAILY /ST 02:00 /F rem cmd /c で囲む方が確実 schtasks /create /TN "Job" /TR "cmd /c cd /d C:\Scripts && run.bat" /SC DAILY /ST 02:00 /F
落とし穴⑤:タスクスケジューラから実行すると「0x1」エラーが出る
最終実行結果が0x1の場合、スクリプトがexit /b 1で終了しているか、コマンドが見つからないことが多いです。まずcmd /c コマンド >> ログファイル 2>&1でログに出力して原因を特定します。
関連記事
- 【bat】schtasksコマンドでタスクスケジューラーを完全管理する完全ガイド(/createの全オプション・XMLインポート・エラーログの詳細解説)
- 【bat】バッチファイルをタスクスケジューラーで実行するとき動作が異なる原因と解決ガイド(作業ディレクトリ・環境変数・ネットワークドライブの問題)
- 【bat】バッチファイルでログ出力する方法完全ガイド(タスクスケジューラからの実行ログを管理する方法)
- 【bat】バッチファイルで条件分岐する方法完全ガイド(ERRORLEVEL・if defined などの条件分岐)
よくある質問
schtasks /run /TN "タスク名"で手動実行して最終実行結果(0x0なら成功、それ以外はエラー)を確認します。/RU SYSTEMはWindowsのSYSTEMアカウントで実行します。パスワード不要でローカルシステムの最高権限を持ちますが、ネットワークアクセスはできません。/RU Administratorsという指定はできません(/RUにはユーザー名またはSYSTEM/LOCAL SERVICEなどを指定します)。管理者グループのユーザーで実行したい場合はユーザー名を明示します。/SC MINUTE /MO 60で60分ごと(=1時間ごと)に実行できます。また/SC HOURLYは存在しませんが、/SC DAILY /RI 60(1時間おきに繰り返し)で毎時間実行する設定もできます。GUIのタスクスケジューラでは「毎時間」の設定がありますが、これはXMLインポートを使えばコマンドでも再現できます。schtasks /change /TN "タスク名" /TR "新しいコマンド"で実行コマンドだけを更新できます。本記事で紹介したインストーラー型バッチ(task_manager.bat)を使えばtask_manager.bat installを再実行するだけで/F上書きで最新の設定に更新されます。