タスク スケジューラの API でタスクの設定を変更する

Windows Vista で導入されたタスク スケジューラ 2.0 の API を使うと、スクリプトなどからタスクを作成して細かい制御をすることができる。

Task Scheduler (Windows)

この API を使って既存のタスクの設定を変更しようとした時ちょっとハマったので、メモとして残しておく。

最初にやったのは、単純に既存のタスクを取得してそのプロパティを変更し保存するというもの。ただ、このやり方だといくらプロパティを変更してもそれが反映されない。

で、どうするかというと、新しくタスクを作って古いタスクの設定をコピーすればいい。それで新しいタスクを上書きモードで登録すると、タスク設定が更新される。

サンプルコードはこんな感じ。ここでは PowerShell を使ったけど、COM な API なので対応していればどんな言語でもいい。

New-Variable TASK_UPDATE 4 -Option Constant
New-Variable TASK_LOGON_INTERACTIVE_TOKEN 3 -Option Constant

$Service = New-Object -ComObject Schedule.Service
$Service.Connect()

$Folder = $Service.GetFolder("\")

$OldTask = $Folder.GetTask("Test")

# 新しいタスクの作成
$NewDefinition = $Service.NewTask(0)
# 古い設定のコピー
$NewDefinition.XmlText = $OldTask.Definition.XmlText

# $NewDefinition をいじくる

[void] $Folder.RegisterTaskDefinition(
    $OldTask.Name, $NewDefinition, $TASK_UPDATE,
    $Null, $Null, $TASK_LOGON_INTERACTIVE_TOKEN, $Null)

API の使い方はリファレンスを読んでもらうとして、ここでのキモは、プロパティを 1 つ 1 つコピーするのではなく、XML による定義をコピーするだけでいいこと。あたかもこのために用意されたかのようなプロパティがあるのがなんか・・・

ちなみに、ログオンしているユーザーとは違うユーザーで実行されるタスクや、ログオンしているかどうかにかかわらず実行されるタスクの場合には、RegisterTaskDefinition メソッドの引数で、実行するユーザーのパスワードを指定する必要がある。