schtasks で XML 定義を取り込む最大のメリットは、タスク設定をテンプレート化して、同じ形で何度でも再利用できることです。毎日実行や毎週実行のような単純タスクなら通常の schtasks /create で十分ですが、実行ディレクトリ、多重起動時の扱い、スリープ復帰、詳細なイベント条件、セッション状態変更トリガーまで含めて揃えたいなら、XML 取り込みのほうが向いています。 (Microsoft Learn)
一方で、XML は実行アカウントやパスの環境差をそのまま抱え込みやすく、手編集した内容は Task Scheduler のスキーマ検証で弾かれます。時間トリガーやカレンダートリガーでは <StartBoundary> が必須で、/xml と /v1 も併用できません。つまり、XML 取り込みは便利ですが、雑に移植すると壊れやすい方法でもあります。 (Microsoft Learn)
schtasks /create /xml の基本
XML 取り込みの基本は、既存タスクを XML に書き出し、それを別名または別端末で登録し直す流れです。schtasks /create では /xml <xmlfile> が使え、必要なら /ru /rp と組み合わせて実行アカウントを上書きできます。すでに XML 側にアカウント情報が含まれている場合は、/rp 単独でも扱えます。なお /v1 は /xml と非互換です。 (Microsoft Learn)
既存タスクをひな型にするなら、まずは書き出しと再登録を 1 回やってみるのが最短です。特定タスクを XML で取り出すときは schtasks /query /tn にフルパスのタスク名を渡します。 (Microsoft Learn)
schtasks /query /tn "\Ops\DailyCleanup" /xml > DailyCleanup.xml
schtasks /create /tn "\Ops\DailyCleanup" /xml .\DailyCleanup.xml /f
タスク名は \Ops\DailyCleanup のようにフォルダー付きで設計しておくと、Task Scheduler Library の直下が散らかりにくく、運用引き継ぎでも迷いにくくなります。 (Microsoft Learn)
XML をゼロから手書きすることもできますが、Task Scheduler の XML はスキーマ準拠が前提です。特に時間系・日次系のタスクでは <StartBoundary> の抜け漏れが起きやすいので、いったん GUI か PowerShell で正しいタスクを作り、そこからエクスポートして編集するほうが現実的です。 (Microsoft Learn)
XML 取り込みが特に効く実用例
複数台に同じ運用タスクを配る
もっとも実務で効くのは、標準タスクの横展開です。たとえば「毎晩 2 時にログ整理」「起動後 5 分で監視エージェントの自己診断」「月初にレポート出力」のようなタスクを、サーバーや端末へ同じ設定で配りたいケースです。1 台の検証機で正しいタスクを作って XML 化しておけば、以後は schtasks /create /xml で再現できます。実行アカウントだけ環境差があるなら、インポート時に /ru /rp で差し替える設計がやりやすいです。 (Microsoft Learn)
この運用で大事なのは、XML とは別に、実行ファイルやスクリプトの配置先も揃えることです。リモート実行の例でも、コマンド内のパスは対象コンピューター側のパスを参照する必要があります。つまり、C:\Ops\Scripts\cleanup.cmd を呼ぶ XML を配るなら、そのパスが全台で成立していることが前提になります。 (Microsoft Learn)
実行ディレクトリや細かい設定まで固定したい
XML が強いのは、schtasks /create の素のスイッチでは表現しづらい設定まで含めて持ち回れる点です。Task Scheduler の Settings には MultipleInstancesPolicy、RestartOnFailure、RunOnlyIfNetworkAvailable、StartWhenAvailable、WakeToRun などがあり、実行アクション側には WorkingDirectory もあります。これらは単純な「毎日何時に起動」より一段運用寄りの設定で、XML にしておく価値が高い部分です。 (Microsoft Learn)
特に判断が分かれるのが多重起動の扱いです。MultipleInstancesPolicy は IgnoreNew が既定で、既存実行中なら新しい起動を無視します。長時間ジョブで「重複実行は避けたいが、次回分は待たせたい」なら Queue、毎回最新の実行だけ残したいなら StopExisting、本当に並列でよい処理だけ Parallel と考えると整理しやすいです。定期実行なのに実行時間が間隔を超えがちなタスクでは、ここを明示しないと意図しない取りこぼしや競合が起きます。 (Microsoft Learn)
差分として見るべき要素は、たとえば次のような部分です。 (Microsoft Learn)
<Settings>
<MultipleInstancesPolicy>Queue</MultipleInstancesPolicy>
<StartWhenAvailable>true</StartWhenAvailable>
<WakeToRun>true</WakeToRun>
</Settings>
<Exec>
<Command>C:\Ops\Scripts\report.cmd</Command>
<Arguments>--daily</Arguments>
<WorkingDirectory>C:\Ops\Scripts</WorkingDirectory>
</Exec>
相対パス前提のバッチや PowerShell がうまく動かないときは、Command ではなく WorkingDirectory の不足が原因のことがよくあります。schtasks の通常スイッチだけで雑に作るより、XML で作業ディレクトリまで固定したほうが再現性は上がります。 (Microsoft Learn)
イベントログやセッション状態で起動したい
/sc ONEVENT があるので、schtasks 単体でもイベント起動はできます。ただし、実務で欲しくなるのは「このログのこのレベルだけ」「イベント XML の値を引数に渡したい」といったもう一段細かい条件です。その場合、XML の EventTrigger で Subscription にクエリ文字列を持たせ、ValueQueries でイベント XML の値を拾ってアクション側の変数として使う構成が有効です。 (Microsoft Learn)
たとえば System ログのレベル 2 イベントに反応させるクエリは、公式ドキュメントでも次の形で示されています。こうした XML ベースの条件は、単純な日次・週次タスクよりも XML 取り込みのメリットが出やすい領域です。 (Microsoft Learn)
<Subscription><![CDATA[
<QueryList>
<Query Id='1'>
<Select Path='System'>*[System/Level=2]</Select>
</Query>
</QueryList>
]]></Subscription>
もう一つの実用例が、セッション状態変更トリガーです。Task Scheduler のスキーマには SessionStateChangeTrigger があり、コンソール接続・切断、リモート接続・切断、ワークステーションのロック・アンロック通知を契機にタスクを起動できます。一方、schtasks /create の /sc 一覧にはこの種類が出てこないので、こうした要件は XML のほうが素直です。端末ロック解除後の同期、RDP 切断時の後処理、接続イベントを起点にしたログ採取などで使いどころがあります。 (Microsoft Learn)
GUI で作ったタスクをテンプレート化したい
XML 取り込みは、GUI で作ったタスクをコード管理に寄せる橋渡しとしても便利です。GUI で一度完成形を作れば、schtasks /query /xml で書き出せますし、PowerShell なら Export-ScheduledTask で XML 文字列として取り出せます。そこから環境依存の値だけ削ったり置換したりすれば、保守しやすいテンプレートになります。 (Microsoft Learn)
失敗しやすいポイント
実行アカウントをそのまま移植する
XML には principal の UserId と LogonType が含まれます。別環境で同じアカウント名やログオン方式が成り立たないと、インポート後に動かない原因になります。共通のサービスアカウントを使う、あるいは XML は共通化して、登録時だけ /ru /rp で差し替える設計にしたほうが失敗しにくいです。 (Microsoft Learn)
「パスワードを保存したくないから資格情報なしで動かす」は、単純そうで詰まりやすい判断です。/np ではローカル リソースしか使えず、S4U ログオンもネットワークや暗号化ファイルにアクセスできません。ネットワーク共有、暗号化された証明書ファイル、ユーザープロファイル依存の処理があるなら、ここを先に確認したほうが安全です。 (Microsoft Learn)
相対パス前提でスクリプトを書く
XML 内の Command だけ合っていても、作業ディレクトリが違えばバッチやスクリプトは簡単に壊れます。設定をテンプレート化するなら、Command と Arguments だけでなく WorkingDirectory までセットで見る癖を付けたほうが、移行時の再現性は大きく上がります。 (Microsoft Learn)
上書き更新で意図せずタスクが走る
登録時や更新時に即時実行したい初期化タスクには RegistrationTrigger が便利です。ただし、このトリガーは更新時にも発火します。/f で上書き更新する運用と組み合わせると、タスク定義の差し替えだけのつもりが、実行まで走ることがあります。セットアップ系や通知系では特に注意が必要です。 (Microsoft Learn)
古い互換性や必須要素を見落とす
旧 OS 互換を意識して /v1 を付けたくなることがありますが、/v1 と /xml は併用できません。また、時間トリガーやカレンダートリガーでは <StartBoundary> が必須です。XML 取り込みで意味の分からないエラーに見えたら、まずは互換オプションの混在と必須要素の欠落を疑うのが近道です。 (Microsoft Learn)
XML 以外を選んだほうが速いケース
1 台だけに「毎日 9 時」「毎週月曜」「ログオン時」のような単純タスクを作るなら、通常の schtasks /create のほうが速いです。/sc には MINUTE、HOURLY、DAILY、WEEKLY、MONTHLY、ONCE、ONSTART、ONLOGON、ONIDLE、ONEVENT が用意されているので、XML を持ち出さなくても十分な場面は多くあります。 (Microsoft Learn)
既存タスクの実行プログラムや実行アカウントだけを直したいなら、schtasks /change が軽い選択肢です。少なくとも /tr、/ru、/rp、/it の変更は公式にサポートされています。XML を毎回編集して再登録するより、変更点が小さいときは change のほうが手戻りが少なくなります。 (Microsoft Learn)
PowerShell 前提の運用なら、Register-ScheduledTask も有力です。-Xml はファイルパスではなく XML 文字列を受け取り、Export-ScheduledTask は XML 文字列を返します。構成管理やスクリプト展開に寄せるなら、こちらのほうが変数展開や前処理を挟みやすいです。 (Microsoft Learn)
$xml = Get-Content .\DailyCleanup.xml -Raw
Register-ScheduledTask -TaskName "DailyCleanup" -TaskPath "\Ops\" -Xml $xml -Force
迷ったら、まず 1 件だけテンプレート化する
最初から全タスクを XML 管理に寄せる必要はありません。まずは手作業で作っている代表的なタスクを 1 件だけ選び、schtasks /query /tn "\フォルダー\タスク名" /xml で書き出してください。そこで UserId、LogonType、Command、WorkingDirectory、Settings のどこが環境依存で、どこが共通化できるかを見極めると、XML 取り込みを使うべき境界がはっきりします。 (Microsoft Learn)
判断に迷ったときの基準は単純です。同じ設定を何度も再現したいなら XML、単純な 1 回設定なら通常の schtasks、PowerShell 運用なら Register-ScheduledTask。この三つに切り分けるだけで、タスクスケジューラ運用の手戻りはかなり減ります。 (Microsoft Learn)

コメント