検索
連載

Windowsでログオフ中でもタスクを起動させる方法Tech TIPS

タスクスケジューラで作成されたタスクは、デフォルトではユーザーが対話的ログオンを済ませた状態でのみ起動できる。だが、だれもログオンせずに稼働させるのが普通のサーバマシンなどでは、この方法は使えない。そこで、ログオフ中でもタスクを起動させる方法を説明する。

PC用表示 関連情報
Share
Tweet
LINE
Hatena
「Tech TIPS」のインデックス

連載目次

対象OS:Windows 7 / Windows 8 / Windows Server 2008 R2 / Windows Server 2012



解説

 TIPS「タスクスケジューラの基本的な使い方(Windows 7/8編)」の手順で作成したタスクは、作成時と同じユーザーアカウントでWindows OSに対話的ログオンを済ませていれば、指定した時刻に起動されるはずだ。しかし、指定時刻にログオフしていると起動に失敗し、次のようなエラーがイベントログに記録される。

ログオフしていたせいでタスクの起動に失敗したことを表すエラー
ログオフしていたせいでタスクの起動に失敗したことを表すエラー
タスクスケジューラの画面で対象のタスクを選択後、その下のペインの[履歴]タブを選ぶと、そのタスクに関するイベント一覧が表示される。この画面はタスクが起動されるはずだった時刻に記録されていたエラーのイベントである。
  (1)イベントIDには「101」が記録されていた。
  (2)このエラー値「2147943645(10進)=0x800704DD(16進)」はWindows OSのシステムエラーコード「0x4DD(16進)=1245(10進)」に相当し、「ERROR_NOT_LOGGED_ON」すなわち「ユーザーがネットワークにログオンしていなかったので要求された処理は実行されなかった」ことを表している(MSDNのシステムエラーコード一覧ページ[英語]の「1245 (0x4DD)」を参照)。

 このままだと、普段は対話的にログオンすることのないサーバマシンや、誰がログオンしているか決まっていない共有PCだと、タスクの定期的な実行はおぼつかない。

 そこで本稿では、対話的ログオンをしていなくてもタスクを自動的に起動するための設定方法を説明する。

操作方法

 ここでは、あらかじめTIPS「タスクスケジューラの基本的な使い方(Windows 7/8編)」のような手順でタスクが作成済みであり、かつログオンしていれば正しく実行されるものとする。また、タスクの実行中は手動で操作しなくても自動的に処理が進み、正常に完了することも確認しておいていただきたい(理由については後述する)。

●タスクの設定を変更してログオフ中でも起動されるようにする

 ログオフ中でもタスクが起動されるようにするには、タスクのプロパティで「セキュリティ オプション」の設定を変更する。それにはまず、[管理ツール]−[タスク スケジューラ]をダブルクリックしてタスクスケジューラの画面を開き、左ペインから対象のタスクを保存してあるフォルダを選択する。真ん中上側のペインに表示された対象のタスクを右クリックして[プロパティ]をクリックすると、[全般]タブの画面下側に「セキュリティ オプション」が表示されるはずだ。そこで[ユーザーがログオンしているかどうかにかかわらず実行する]ラジオボタンを選択する。

タスクの設定を変更してログオフ中でも起動されるようにする
タスクの設定を変更してログオフ中でも起動されるようにする
これはタスクスケジューラの画面から、対象のタスクのプロパティを開いたところ。[全般]タブにある「セキュリティ オプション」枠内の設定を変更する。
  (1)このタスクを起動するユーザーアカウント。デフォルトでは、タスク作成時のログオンユーザーが指定されている。
  (2)デフォルトではこちらが選択されている。この場合、(1)のユーザーアカウントで対話的にログオンしていないと起動に失敗する。
  (3)こちらを選ぶ。これにより対話的にログオンしていなくても起動できるようになる。
  (4)これにチェックを入れてオンにすると、この後に説明するパスワード入力が不要になる半面、タスクから共有フォルダのようなネットワーク上のリソースにアクセスできないなどの制限が生じる。本稿ではオフのままとする。
  (5)ユーザーアカウント制御(UAC)が有効で、かつタスク実行中に管理者権限を必要とする処理がある場合は、これにチェックを入れてオンにする。
  (6)これをクリックすると、(1)に対応するパスワード入力を求めるダイアログが表示される。→[A]

 「セキュリティ オプション」でほかに設定を変更するとすれば、(5)の[最上位の特権で実行する]チェックボックスである。もし、このタスクの実行時にユーザーアカウント制御(UAC)のダイアログが表示され、管理者権限での実行を求められることがあるなら、これにチェックを入れてオンにする。また上記の設定変更後にタスクを実行してアクセス拒否のエラーが生じた場合も、このチェックボックスをオンにするとエラーが解消されることがある。

 さて、上記画面で[OK]ボタンをクリックすると、次のパスワード入力ダイアログが表示されるので、[ユーザー名]欄のユーザーアカウント(=上の画面の(1))に対応するパスワードを入力して[OK]ボタンをクリックする。これらは資格情報として保存され、このタスクを実行する際のログオンに利用される。

[A]

タスクを実行するユーザーアカウントのパスワードを入力する
タスクを実行するユーザーアカウントのパスワードを入力する
タスクのプロパティ画面で[OK]ボタンをクリックすると、このダイアログが表示される。表示されたユーザーアカウントに対応するパスワードを入力して[OK]ボタンをクリックする。

 なお、このパスワード入力ダイアログは、コマンドラインなど一部のタスク設定を変更するたびに表示されるので、その都度パスワードを入力すること。

●管理者ではないアカウントには「バッチとしてログオン」という権利が必要

 タスクを実行するユーザーアカウントに管理者権限があれば、以上で設定は完了である。しかし管理者でないユーザーアカウントの場合、次のダイアログが表示される。

「バッチ ジョブとしてログオン」の権利がないことを警告するメッセージ
「バッチ ジョブとしてログオン」の権利がないことを警告するメッセージ
これはタスクの実行アカウントに管理者権限がない場合に表示されるメッセージ。タスクのプロパティで[ユーザーがログオンしているかどうかにかかわらず実行する]を選択した場合、タスクを実行するアカウントは対話的ログオンではなく、「バッチログオン」を行う。それに必要なのが、この「バッチ ジョブとしてログオン」という権利である。これはデフォルトで管理者(ローカルAdministratorsグループ)には割り当てられているが、一般ユーザーには割り当てられていない。

 対話的ログオンなしでタスクを実行するには、この「バッチ ジョブとしてログオン」という権利が必要になる。しかし管理者権限のないユーザーアカウントにはデフォルトでこの権利が割り当てられていないため、明示的に割り当てる必要がある。それにはまず、管理者権限のあるユーザーアカウントで[管理ツール]−[ローカル セキュリティ ポリシー]を実行し、左ペインで[ローカル ポリシー]−[ユーザー権利の割り当て]を選び、右ペインで[バッチ ジョブとしてログオン]をダブルクリックする。

「バッチ ジョブとしてログオン」の権利を実行アカウントに割り当てる(その1)
「バッチ ジョブとしてログオン」の権利を実行アカウントに割り当てる(その1)
これは管理者権限のあるユーザーアカウントで[管理ツール]−[ローカル セキュリティ ポリシー]を起動したところ。
  (1)これを選ぶ。
  (2)これをダブルクリックする。→[B]

[B]

「バッチ ジョブとしてログオン」の権利を実行アカウントに割り当てる(その2)
「バッチ ジョブとしてログオン」の権利を実行アカウントに割り当てる(その2)
  (1)この権利が割り当てられているユーザーやグループ。ローカルAdministratorsグループは最初からこの欄に記載されているはずだ。
  (2)これをクリックする。→[C]

[C]

「バッチ ジョブとしてログオン」の権利を実行アカウントに割り当てる(その3)
「バッチ ジョブとしてログオン」の権利を実行アカウントに割り当てる(その3)
  (1)指定するユーザーアカウントに合わせて、ローカルコンピュータかドメイン、あるいは「ディレクトリ」全体のいずれかを選ぶ。
  (2)タスクを実行するユーザーアカウント名を入力する。

 あとは[OK]ボタンをクリックしていってダイアログを閉じれば設定完了だ。

●ログオフ中でもタスクを起動できるかどうか試す

 設定変更が済んだら、早速実行できるかどうか試してみよう。タスクスケジューラの画面で該当タスクを右クリックして[実行する]をクリックすると、即座にそのタスクが起動される。正常であれば、設定変更前と同様にタスク実行が完了し、処理結果が残るはずだ。完了したかどうかは、タスクスケジューラの画面の真ん中上側ペインに表示されるタスク一覧で、[前回の実行結果]列に「この操作を正しく完了しました」と表示されるかどうかで判断できる。

 成功したなら、次は、例えば5分後にタスクが起動されるようにスケジュールを変更してから、ログオフするかシステムを再起動する(スケジュールの設定手順は前掲のTIPS参照)。そして5分たってタスクが完了した頃を見計らって(対話的に)ログオンし、再度タスクスケジューラの画面を開いて該当タスクの[前回の実行結果]を確認する。

●完了できなくなったタスクを強制的に止める方法

 もし、実行したタスクの[前回の実行結果]がいつまでたっても「現在タスクを実行中です。」のままなら、何らかの理由でタスクが完了できない可能性がある。

 タスクの設定で[ユーザーがログオンしているかどうかにかかわらず実行する]を選択した場合、同一アカウントで対話的にログオンしていない限り、そのタスクはバックグラウンドで実行される。そのため画面出力は表示されず、キーやマウスの入力も受け付けられない。その結果、例えばタスクがユーザーによるキー/マウス操作を待っている状態に陥ると、いつまでたってもそのタスクは自律的に終了できなくなる。

 このような場合にタスクを終了させるには、該当タスクを右クリックして[終了]を選ぶ。

タスクを強制的に終了する
タスクを強制的に終了する
タスクスケジューラの画面で該当タスクを選択したところ。
  (1)タスクが実行中の場合、[前回の実行結果]列に「現在タスクを実行中です」と表示される。正常に完了すると「この操作を正しく完了しました」、エラーを伴って終了した場合はその内容がそれぞれ表示される。
  (2)該当タスクを右クリックして表示されるメニューから、これをクリックすると、タスクが強制的に終了される。


 以下のコラムにも記しているように、ログオフ中でも起動されるようにタスクの設定を変更すると、実行中に何らかのエラーが生じるようになることがある。これは、タスク実行時のログオンの種類が対話的ログオンからバッチログオンに変わることが大きく影響している。その対処方法は複雑なので、今後、あらためて紹介する。

【やって分かった】タスクによってはログオフ中の実行に失敗することがある

やって分かった

 筆者が作成した複数のタスクに対して、本文で説明したように設定してログオフ中に実行してみたところ、実行中にエラーが発生して正常に実行できないタスクが幾つかあった。その具体例を2つ挙げる。

 1つは、ドライブ名を割り当てたネットワークドライブへのアクセスである。まず、あらかじめ特定のドライブ(ここではS:ドライブとする)にネットワーク共有フォルダを割り当てておく(ログオン時に自動で割り当てるようにも設定しておく)。そしてタスクとして実行するバッチファイル中で、「S:\work\temp.log」というパスのファイルにアクセスする処理を記述したとする。タスクの設定で[ユーザーがログオンしているときのみ実行する]を選ぶと、この処理は成功する。しかし[ユーザーがログオンしているかどうかにかかわらず実行する]を選ぶと、「指定されたパスが見つかりません。」というエラーが発生してしまう。

 この場合、パスの記述を「\\Server1\Share01\work\temp.log」というようにUNCへ変更すると、正常に実行できるようになった。また、次のようにバッチファイル内でドライブ名の割り当てと解除をしても成功した。

net use S: \\server1\Share01 ……ドライブ名の割り当て
……
(「S:\work\temp.log」にアクセスする処理を記述)
……
net use S: /delete /yes ……ドライブ名の割り当て解除



 もう1つは、管理者ではないユーザーアカウントの下でOfficeアプリケーションによる自動処理をしていた場合である。具体的にはVBScriptによるスクリプトからExcelを起動してVBAを自動実行し、Excelブックを生成するという処理の際、次のようなDCOMのエラーが発生した。

Excelによる自動処理をするタスクで発生したDCOMのエラーの例
Excelによる自動処理をするタスクで発生したDCOMのエラーの例
Excelには、VBAでExcelブックを自動生成させている。[ユーザーがログオンしているかどうかにかかわらず実行する]を選ぶと、必ずこのエラーが発生する。

 このエラーは本稿執筆中に解消できなかった(正確にはDCOMのエラーは解消できたが、Excelブックの生成に失敗する症状に変わりはなかった)が、もし今後解決できたら別稿で原因と対策を詳しく解説したい。


「Tech TIPS」のインデックス

Tech TIPS

Copyright© Digital Advantage Corp. All Rights Reserved.

ページトップに戻る