目次

【Windows10】PowerShell スクリプトをタスクスケジューラで定期実行する


タスクスケジューラでPowerShellスクリプトを定期実行しようとしたら思いのほか苦労した話。

タスクスケジューラを利用して定期実行処理を作成する

単純な処理を定期的に時効する手段として、Windowsには標準機能でタスクスケジューラという機能がある。これを利用すると定期的にプログラムを実行することが可能である。

このタスクスケジューラにBatファイルを登録して定期実行することは今までに何度かあったが、今回、少し凝った処理をしようとしてPowershellでスクリプトを書いたところ、「時間通りに起動するものの即座に終了する」という、いわゆる「空振った」処理が発生してしまい、解決までになかなかハマってしまった。

結論

以下のような設定が必要となる。

  1. 「プログラム/スクリプト」は自作のps1ファイルを指定するのではなく、poweshell.exe を指定する
  2. 引数には -ExecutionPolicy Bypass -Command <ps1ファイル> を設定する
  3. スクリプト内部でさらに別のps1ファイルを実行するときにも -ExecutionPolicy Bypass を付与する

ここに辿り着くまでに2時間程かかってしまった。わかってしまえばなんのことない内容だが、備忘録兼ねて整理する。

https://res.cloudinary.com/dlhmnejhz/c_scale,f_auto,q_auto,w_1200/2022-02-19223137_apvsyf.png
powershell スクリプトをキックするためのタスクスケジューラ設定

「プログラム/スクリプト」の設定について

bat処理をタスクスケジューラから実行する場合には、自作した batファイル をタスクスケジューラの「プログラム/スクリプト」に設定しておけば良い。

この考え方を持って、自作したps1ファイルをタスクスケジューラで定期実行しようとしたところ、「スクリプトが起動後に終了する」現象に行き当たった。

ログを出力するようにしてもログすら出力されず、「起動するものの処理が開始されず終了」しているように見受けられた。

結論から言うと、これはWindowsのPowerShellスクリプトの安全装置が原因であった。

実行ポリシーについて - PowerShell

PowerShell の実行ポリシーについて説明し、その管理方法について説明します。

コマンドプロンプトはクリックすると即座に処理が開始されてしまうため、悪意のある操作等ができてしまう側面があった。

PowerShellはそうした問題に対応するために、あらかじめ、

  • Windows端末では、コマンドは許可するものの、スクリプト(ps1ファイル)は許可しない
  • Windowsサーバでは、スクリプト(ps1ファイル)は許可されているが、インターネットから入手したファイルの場合、電子署名がないスクリプトは許可しない

設定が適用されているのである。

そのため、 タスクスケジューラの設定としては、powershell.exeを起動した後、特定のスクリプトファイルだけ実行ポリシーを変更して実行する 処理が必要となる。(あるいは、システム全体の設定で全てのスクリプトを起動可能とすることも考えられるが、推奨はしない)

そのため、まずはPowerShellの実態である、powershell.exeを呼び出し、その powershell.exe にオプションで後続処理のポリシー変更を設定することがポイントとなる。「プログラム/スクリプト」で呼び出すpowershellファイルは、Windows10の場合、具体的には

プログラム/スクリプト
1
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

となる。

引数の設定について

powershell.exe を呼び出したあと、引数を利用して、自作したスクリプトファイルと、ポリシー変更を設定する。この設定は具体的には、

引数の追加
1
-ExecutionPolicy Bypass -Command "<ps1ファイルまでの絶対パス>"

となる。 -ExecutionPolicy Bypass は前述のスクリプトのポリシー設定である。ここでの設定は

-ExecutionPolicy
現在のセッションの既定の実行ポリシーを設定し、 $env:PSExecutionPolicyPreference 環境変数に保存します。 このパラメーターでは、レジストリに設定されている Windows PowerShell 実行ポリシーは変更されません。

とのことなので、影響範囲はタスクスケジューラの処理だけとなり、悪影響は考え難い。

次に重要なのが -Command "<ps1ファイルまでの絶対パス>" の設定である。これは -File "<ps1ファイルまでの絶対パス>" でもおそらく問題はない。

CommandオプションとFileオプションの違いは、

  • Commandオプション – 後続の処理を標準出力として処理する
  • File オプション – 後続の処理はスクリプトファイルである必要がある

ようだ。今回は、Fileオプションの存在より先にCommandオプションを知ったため、Commandオプションを利用している。

ちなみに、タスクスケジューラから呼び出されるPowerShellスクリプトからさらに別のPowerShellスクリプトを実行させた際にFileオプションを設定してみたところ、不都合なく起動することができたので、タスクスケジューラの引数設定時に -File オプションを利用してもおそらく問題はない。

PowerShell exe について - PowerShell

"powershell.exe" コマンド ライン インターフェイスの使用方法について説明します。 コマンド ライン パラメーターを表示し、構文について説明します。

PowerShellがコマンドプロンプトと違っていろいろなことができるようになった。 反面、今回のような、実行制御ポリシーなど、コマンドプロンプトを利用している際には意識していなかった設定が追加されていることが今回詰まった原因でした。