社内SEの話

日々起きたことの記録用

タスクスケジューラでPowershellが実行できない時の勘所

こんにちは、はじめまして。めじろです。

Powershellで作ったスクリプトをタスクスケジューラで実行するケースは比較的多いです。
ただスケジューラを設定しても動かない、動いていないなんて事もよくあります。

タスクスケジューラからPowershellを実行するときのコツを挙げていきます。

タスクスケジューラから実行されない

作ったら必ずテスト実行をする

タスクスケジュールを登録してそのままスケジュールまで待つのではなく、一度実行テストの必要があります。
所定の時間や動作をさせるテストもあると思いますが、まずタスクスケジューラ越しで実行できるか確認してみてください。
でないと実行できなかった時の問題の切り分けができなくなり、沼にハマります。

どのバージョンで作ったPowerShellか?

PowerShell1.0や2.0などはSJISで、最新のバージョンは7.x系はUTF8になります。
実行するバージョンと作ったps1の文字コードが違う場合、当然ながら実行されません。

作ったバージョンと実行するバージョンを揃える必要があります。
下記のパスをプログラム/スクリプトに入力する必要があります。

Powershell1.0

%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe  

Powershell7.0

"C:\Program Files\PowerShell\7\pwsh.exe"  

途中で止まる

開発時にはそこまで意識していないカレントディレクトリが、タスク実行時は大きな影響になります。
スクリプト内で相対パスでファイル指定などをしている場合はパスを見つけられず、エラーとなり止まってしまいます。

対処1 開始オプションに入れる
開始オプションに実行するスクリプトのカレントディレクトリを指定できます。とりわけ相対パスで作られたスクリプトの場合は必須になります。

対処2 スクリプト内で移動する
スクリプト内で.ps1の場所に移動するスクリプトを事前に書き込んでおく事もできます。
この場合はどの開発環境・本番環境、別環境であってもわざわざカレントディレクトリを意識しなくても.ps1ファイルのある場所がカレントディレクトリになるので便利です。

Set-Location -Path ( [System.IO.Path]::GetDirectoryName($myInvocation.MyCommand.Definition))  

パスが正しいか

運用中に遭遇するケースですが、スクリプトを移動してしまいパスが見つけられずエラーとなり実行できない事もあります。
この場合は元の場所に戻すが、現在の場所を引数の追加を修正すればいいと思います。
盲目的にならず、実行できない場合はパスの確認も必要です。

スケジュール通りに実行できない

最上位権限ではない

セキュリティ上の問題がなければ、最上位権限は入れておいた方がいい。
タスクスケジュールは実行時のログインの状態、ユーザーの権限等で権限が複雑になりがちです。
問題を回避するから最上位権限を推奨。
ただセキュリティ面や実行時の状態が明確になっている場合はその限りではないです。

条件が一致していない

条件タブは基本いじらないが、もしいじっていたら条件の意味を確認してもらい、修正してもらいたいと思います。

アイドル状態の場合のみタスクを開始する

まずアイドル時とは

docs.microsoft.com

・15分ごとアイドル状態を確認している
・ユーザーの不在状態とリソースの消費量が少ないのが条件
・ユーザーの不在状態とはマウス・キーボード入力がない状態
これらがアイドル状態を指しているようです

電源

PCに電源供給のある場合が該当します。バッテリー駆動中のノートPCは該当しません。

有効期限が過ぎている

有効が外れている

レアケースですが長期間運用していると、たまに有効が外れています。
なにかの拍子に外したもののそのままになっており、実行されないこともありえます。