質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%

Q&A

解決済

2回答

249閲覧

Pythonでのタスクスケジューラー設定

退会済みユーザー

退会済みユーザー

総合スコア0

0グッド

0クリップ

投稿2024/11/11 03:33

編集2024/11/13 05:14

実現したいこと

Pythonでシャットダウンやログオフ前にファイルを実行するタスクを
タスクスケジューラーに作成したいです。

仕様
Pythonでログオフ直前にbatファイルを実行するタスクをタスクスケジューラーに設定し
batファイルは起動したらjsonファイルにログオフ時間を記録する

※将来的にはPythonをexeファイルに変換し、配布する予定です。

発生している問題・分からないこと

イベントビューワーに保存されているID=7002をトリガーとして
Pythonにて設定しましたがログオフやシャットダウンしても指定したbatファイルが動きません

該当のソースコード

import subprocess # subprocessモジュールをインポート # バッチファイルのパス batch_file_path = 'C:\\Users\\user\\Desktop\\log.bat' # タスクの名前 task_name = 'RunBatchOnDisconnect' # タスクを作成するコマンド、XPathクエリ内のシングルクオートをエスケープ command = ( f'schtasks /create /tn "{task_name}" /tr "{batch_file_path}" /sc ONEVENT ' f'/ec System /mo "*[System[Provider[@Name=\'Service Control Manager\'] and EventID=7002]]"' ) # コマンドを実行 try: subprocess.run(command, check=True, shell=True) print("タスクが正常にスケジュールされました。") except subprocess.CalledProcessError as e: print(f"エラーが発生しました: {e}")

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

検索した結果下記のように設定すればいけると思いましたがうまくいきません
イメージ説明
イメージ説明

補足

特になし

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2024/11/12 09:49

いきなり最終形のテストをしているように見えます。 Pythonプログラムを作るのは、まず「手作業でタスクスケジューラー画面からタスクを登録してみてうまく行った」とこを確認してからですが、そこはOKで期待通りの動作をしたというなのでしょうか? ActiveDirectoryを使っていれば、ログオフスクリプトを登録できるはずですが、ADを使ってないということですかね。
退会済みユーザー

退会済みユーザー

2024/11/13 05:19

期待通りには動作しておりません。まず手作業での設定につまずいておりました。 ActiveDirectoryというのに知見がなかった為、調べてみます。 ありがとうございます。
otn

2024/11/13 06:34

> まず手作業での設定につまずいておりました。 手作業の設定段階での問題であれば、Pythonは全く関係ありませんね。 ActiveDirectoryに知見がないと言うことは、現時点では使っていないということでしょうか? AD導入からだと設計含め、大仕事になりますね。それが良いのかどうか。 「ID=7002 を拾えば良い」というのは実績があることなのでしょうか?
退会済みユーザー

退会済みユーザー

2024/11/14 07:50 編集

otn様 ご回答ありがとうございます。 >ActiveDirectoryに知見がないと言うことは、現時点では使っていないということでしょうか? →現時点では使っていないです。 「ID=7002 を拾えば良い」というのは実績があることなのでしょうか? →実績はありません。 hiroki-o様 ご回答ありがとうございます。 また、qiitaの方も見ていただきありがとうございます。 そちらに関してはまだ検証できておりませんがhiroki-o様としては qiitaで頂いたご意見はいかがでしょうか?
guest

回答2

0

シャットダウン前に実行するというプログラムは無理だと断定しました。
やはりシャットダウン処理が入ってしまい、処理中のプログラムも中断してしまいました。

シャットダウン時間についてはスタートアップ時に、ID=7002をイベントビューワーから
拾ってきて、その時間を記録することにしました。

皆様ご協力いただきありがとうございました。

投稿2024/11/22 12:35

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

「ID=7002 を拾えば良い」というのは実績があることなのでしょうか?
→実績はありません。

そうすると、「何故7002?」ということになりますね。

「イベントを拾ってからプログラムを起動」というのは、シャットダウンやログアウト処理が発生するよりずっと前に発生するイベントを拾う必要があると思いますが、そういうイベントがあるのか?それをどうやって調べるのか?と言うことになるかと思います。

ActiveDirectoryを使っていれば、ログオフスクリプトを登録できるはずですが、ADを使ってないということですかね。

と、コメントに書きましたが、ADは必要なさそうです。
企業なので、Windows はHomeじゃなくてProですよね?
グループポリシーエディター(gpedit)の、「コンピューターの構成」「ユーザーの構成」それぞれの「Windowsの設定」の下に、それぞれ「スクリプト(スタートアップ/シャットダウン)」と「スクリプト(ログオン/ログオフ)」があるので、シャットダウンとログオフに登録すれば出来ると思います。
自宅PCは、ADを使ってないのですが、ログオフにBATファイルを登録するとサインアウト時に動きました。

ただ、これをGUIでなく、プログラムから行う方法は1分くらいググった程度ではよくわかりませんでした。PowerShellを使うと、AD下の場合は少なくとも参照は出来るようなので、何らかの手段で設定も出来るかもしれませんが、ADじゃないと参照も出来ないですね。

別案では、「プログラム終了指示イベントを拾える言語を使って、プログラム終了指示イベントを待ち続けてイベントが来たらやりたい処理をする」プログラムをログオン時やOS起動時に実行する。
これは出来るはずですが、Windowsで具体的にどうプログラムするかは知りません。
OSシャットダウン操作をすると、「これらのプログラムが妨げています」のような表示が出て、戻ってみると、プログラムが「変更を保存しますか?変更を捨てますか?」のようなダイアログを出しているという経験がおそらくあると思いますが、そのプログラムは「プログラム終了指示イベント」を拾ってそういう処理をしていると言うことです。というふうにポピュラーな機能なのでその気になって調べれば具体的手段は分かるかと思います。

また、そもそも、「batファイルは起動したらjsonファイルにログオフ時間を記録する」だけが目的あれば、ログオフ時には何もせずに、「必要な都度イベントログを見る」で良いかと思います。毎回ログイン時に、前回ログオフ時のイベントを調べてファイルに書いても良いし。
他にもやりたいことがあるとかだと駄目ですが。
あるいは、ログオフ時刻を書くファイルがローカルファイルじゃなくてファイルサーバー上に書いて、シャットダウン中のPCについてもファイルサーバーを見ることで最終ログオフ時刻を知りたいとかの場合も駄目ですね。

投稿2024/11/14 10:54

otn

総合スコア85785

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2024/11/14 11:32

そうすると、「何故7002?」ということになりますね。 →自分の検証にてシャットダウン・ログオフ時で必ずイベントID=7002が発生しており、調べると  ログオフ通知に関することでしたので、こちらを元に仮説を立てて検証していました。  結果は成功せずの為迷走してしまいました。 企業なので、Windows はHomeじゃなくてProですよね? →Proになります。gpeditで設定にはたどりつきましたが、Python側でgpeditを設定する方法は  いくら調査しても不明でしたのでタスクスケジューラー側に倒しました。  しかし他の方のご意見でも頂き、PowerShellでの実行を見落としていたため、一度検証してみます。   プログラム終了指示イベントを拾える言語を使って、プログラム終了指示イベントを 待ち続けてイベントが来たらやりたい処理をする。 必要な都度イベントログを見る ファイルサーバー上に書いて →代替案いただきありがとうございます!!  一度こちらも案に入れて検討してみたいと思います。
otn

2024/11/14 12:06

> Python側でgpeditを設定する方法はいくら調査しても不明でしたの Pythonにも、GUIプログラムに対してのマウス操作やキーイン操作を行うライブラリーがあるかと思うので(「Python RPA」で検索すると複数あるようです)、そういうのを使って、gpedit画面を操作するか、 (たまにそういうライブラリについての質問も見かけます) 汎用のRPAツール(Windows標準の物とか)を使ってgpedit面を操作するスクリプトを書いて、Pythonからはそれを起動するとか。 「自分本人が使うだけ」なら、スタートメニューからのシャットダウンを止めて、その代わりに「やりたい処理をやってからシャットダウンするスクリプト」(これは簡単に書ける)を実行すれば良いのですが、他人には徹底させられないので駄目でしょうね。個人的にはよく使う手です。
otn

2024/11/14 12:16

> 自分の検証にてシャットダウン・ログオフ時で必ずイベントID=7002が発生しており、 シャットダウン操作をした瞬間で、まだ本格的にシャットダウン処理が始まるまでに時間の余裕があるものである必要があるでしょうね。 シャットダウンでなく、ログオフ限定であれば、タスク登録時に 「ユーザーがログインしているかどうかに関わらず実行する」にすれば出来るかも知れません。 試してませんが。 シャットダウンだと、シャットダウン処理に入っちゃうだろうから、上記のように設定しても、プログラム起動がうまく行かない気がします。気がするだけなので、もしかすると出来るかもですが。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問