ローカルコンピューターポリシーのシャットダウンスクリプトからタスクスケジューラに登録されたタスクを実行した際にタスクから起動されるbatファイルの実行に失敗する

Anonymous
2024-11-13T06:27:34+00:00

やりたいこと:

  • Windowsがシャットダウンや再起動が掛かった際に、ローカルユーザー権限でコマンドを実行してから、システムの終了・再起動をさせたい

実行環境:

  • OS:Windows 11 Pro 64bit (24H2)

実施した内容:

  • タスクスケジューラーにて以下のタスクを登録
    全般
    ・タスクの実行時に使うユーザーアカウント=実行したいローカルユーザー ・最上位の特権で実行する
    操作
    ・プログラムの開始=実行したいコマンドを記載したbatファイルを指定
     
    →他のローカル管理者ユーザーから手動でタスクを実行した場合に、問題無く実行されることは確認済み
  • グループポリシーエディタ(gpedit.msc)からシャットダウンスクリプトを登録
    コンピューターの構成 > Windowsの設定 > スクリプト(スタートアップ/シャットダウン) > シャットダウン に
    タスクスケジューラに登録したタスクを実行するbatファイルを登録(下記内容)
    schtasks /run /tn "登録したタスク名" <br><br>timeout /nobreak 30
    →ローカル管理者ユーザーから手動でbatファイルを実行した場合に、問題無く実行されることは確認済み

発生した問題:

  • 実際にシステムをシャットダウン・再起動した際に、シャットダウンスクリプトが実行されてタスクが実行されるが下記のエラーとなりbatファイルの実行に失敗してしまう
    タスク スケジューラは、タスク "\登録したタスク名" のインスタンス "{63eb18fa-6956-4957-b59a-b45f83e1b613}" の操作 "C:\WINDOWS\SYSTEM32\cmd.exe" の起動に失敗しました。追加データ: エラー値: 2147943515。

このような実行方法をとった経緯としては、

まず、タスクスケジューラーから「システム終了のイベントID」をトリガーとして実行するようタスク登録してみましたが、シャッタダウン時に強制終了されてしまい失敗してしまったため、グループポリシーのシャットダウンスクリプトから実行する方法にたどり着きました。

ところが、今度はbat実行時にcmd.exeの起動に失敗という想定外のエラーが出てしまい、行き詰まっています。

どなたか解決方法やヒントを頂けませんでしょうか。

宜しくお願いいたします。

***Move from Windows / Windows 11 / establishment***

ビジネス向け Windows | IT プロフェッショナル用 Windows クライアント | パフォーマンス | その他

ロックされた質問。 この質問は、Microsoft サポート コミュニティから移行されました。 役に立つかどうかに投票することはできますが、コメントの追加、質問への返信やフォローはできません。 プライバシーを保護するために、移行された質問のユーザー プロファイルは匿名化されます。

0 件のコメント コメントはありません
{count} 件の投票

5 件の回答

並べ替え方法: 最も役に立つ
  1. Anonymous
    2024-11-14T02:30:22+00:00

    ちょうどアップデートによる自動再起動が掛かりましたので、その際のタスクスケジューラのログ詳細を添付します。

    宜しくお願いいたします。

    0 件のコメント コメントはありません
  2. Anonymous
    2024-11-14T06:35:59+00:00

    チャブーンです。

    この件ですが、このエラーコード"0x8007045B"はERROR_SHUTDOWN_IN_PROGRESSという意味になります。シャットダウン中に何らかの問題でエラーになった、という一般的なエラーです。

    画面ショットは見ましたが、SupendVM_at_Suntdown でやらせている、具体的な中身は何なのでしょうか?タスクの内容が、Hyper-Vゲストマシンに対する何らかの操作、ということでしたら、シャットダウン中はHyper-Vサービス自身がシャットダウンしてしまうので、この状況でのエラーなら、さもありなん、という内容です。

    シャットダウン中に特定サービスだけ遅延、ないしは依存関係を持たせる、ということは困難です。なので、実施要件を変えるか、シャットダウンではなくログオフで実行、その後シャットダウンという2段階操作が必要なのではないでしょうか?予想が当たっていればですが。

    ちなみに単にHyper-Vのサスペンド or シャットダウンを担保したい、という場合ですが、Hyper-V自体にその機能がついてますので、大丈夫です。仮想マシンをサスペンドするなら、特段の設定はいらない(Hyper-V側で対応するから)理解です。事前シャットダウンの場合、統合ソフトウェアがゲスト側にインストールされている必要があります。Windowsの場合はOSに組み込まれてますので問題ないです。非Windowsの場合は確認いただく必要があります。

    Hyper VisorソフトウェアがHyper-Vでない、というなら、その製品の指示に従ってください、が当座の答えになると思います。

    0 件のコメント コメントはありません
  3. Anonymous
    2024-11-14T07:26:23+00:00

    チャブーンさま

    お返事ありがとうございます。

    ローカルコンピューターポリシーのシャットダウンスクリプトが実行完了するまで

    その他のシャットダウン処理は保留されプロセスも停止されない

    と認識しており、スクリプト中に『timeout』も入れてその間に処理を終わらせることを想定していました。

    そもそもこの認識が誤っているでしょうか?

    イベントID: 1074でひとたびシャットダウンプロセスが開始してしまうと

    シャットダウンスクリプトの実行を待たずに既存プロセスを落とし始めてしまうでしょうか。

    実行したい内容については、ご推察の通り実行中のVMに対する処理(サスペンド指示)です。

    ただハイパーバイザーはHyper-VではなくVMware Workstationです。

    batファイルからCLIコマンドにてサスペンドを実行しているのですが

    VMware側の仕様によりVMを起動したアカウントからでないとCLIが効かないため

    タスクマネージャにVM起動アカウント権限で処理を実行するよう登録してあります。
    初めに記載の通り、他のローカル管理者ユーザーから手動でタスクを実行した場合には
    問題無く実行されることは確認済みであり、少なくともタスクスケジューラーのエラーに関しては

    VMwareの問題では無いと切り分け出来ていると思っておりVMwareの情報はあえて出していませんでした。
    (「cmd.exe" の起動に失敗」というログメッセージの通りであるならば)

    実現したいことを改めてまとめますと、

    Windowsのシャットダウン・再起動時に、起動中のプロセスが落とされ始める前に

    任意のユーザー権限でコマンドを実行・完了させてからシステム終了・再起動させたい

    ということになります。

    そのための方法として、ローカルコンピューターポリシーのシャットダウンスクリプトならば

    可能なのではと考え、試行錯誤しているところです。

    他に何か考えられる懸念点などございましたら、コメント頂けますと幸いです。

    宜しくお願いします。

    0 件のコメント コメントはありません
  4. Anonymous
    2024-11-14T10:54:48+00:00

    チャブーンです。

    やはりそうでしたか。

    > イベントID: 1074でひとたびシャットダウンプロセスが開始してしまうと

    > シャットダウンスクリプトの実行を待たずに既存プロセスを落とし始めてしまうでしょうか。

    残念ですが、まったくその通りです。シャットダウンスクリプトでは「環境の保全」を保証しません。Windows用語では「同期的実行」は行わない、になります。

    古いWindowsの仕様ですが、以下に資料があるようです。

    Working with startup, shutdown, logon, and logoff scripts using the Local Group Policy Editor | Microsoft Learn

    シャットダウン時のスクリプト挙動の制御は難しい認識ですので、以下の対応でうまくいくかどうか、試行していただくことになると思います。

    1. 高速スタートアップ機能を無効にする
      昔のWindowsは起動シャットダウンにのどかに時間を使いましたが、最近のWindowsでは素早い立ち上げと停止が要求されます。その機能が高速スタートアップですが、これを無効にすると、旧来のWindowsの挙動に近くなり結果うまくいく可能性があります。
      無効化の方法はWindows10/11の高速スタートアップの無効方法【デメリット・できない時の対処も】 (itojisan.xyz)などを見てみてください。
    2. スクリプト内で同期的実行になるようプログラムする
      上記で対応できない場合、強制的に同期的実行を行わせるよう、スクリプトに組みこむことになります。WMIの機能で特定プロセス(batファイル実行なので、cmd.exeプロセスになると思いますが)が終了するまでスクリプトを終了させない、というものです。実例がありますので(ここではBestSyncSvc.exeプロセスを監視しています)参考にしてみてください。How to Execute Sync Tasks During Windows Logoff or Shutdown? (risefly.com)
      ただし、状況からbatファイル実行前にエラーになっているようですので、このセンでの解決は今は薄いと思われます。
    0 件のコメント コメントはありません
  5. Anonymous
    2024-11-21T07:40:25+00:00

    チャブーンさま

    お返事ありがとうございました。

    期待した動作が失敗となる原因の裏付けとなる情報を共有頂き、ありがとうございます。

    『高速スタートアップ』については既に無効となっていました。

    プログラムの作成についても共有頂いたリンク先の情報を参考にVBSスクリプトを作成しシャットダウンスクリプトに登録してみましたが、

    • 手動で実行したときは想定通りに実行される
    • シャットダウン時にはタスク実行時に「"cmd.exe" の起動に失敗しました」のエラーが出てしまう

    というこれまでと同様の結果でした。

    スクリプトをPowerShellにしてみたりと色々試したのですが結果は変わらずでした。

    これまで試した中で一番可能性が有りそうなのが、タスクスケジューラから イベントID:1074 をトリガーとして

    サスペンド実行バッチを実行するパターンでした。

    手動で shutdown /r /t 0 コマンドを発行すると、イベントID:1074が発行されてから若干(数秒)の

    猶予が有るように思われ、数回ですがサスペンドできるケースが確認出来ました。

    イベントビューアとタスクスケジューラの履歴ログを時系列にすると以下となっていました。

    16:15:37  1074  再起動指示
    16:15:38  Task  108 イベントによってトリガーされるタスク(タスクのインスタンス起動)
    16:15:38  Task  129 タスクのプロセスが作成(cmd.exe起動)
    16:15:38  Task  100 タスクの開始(タスクのインスタンスを開始)
    16:15:38  Task  200 開始された操作(cmd.exeを開始)
    16:15:41  Task  201 操作が完了(cmd.exeを正常に完了)
    16:15:41  Task  102 タスクが完了(タスクのインスタンスを正常に完了)
    16:15:44  7002  ユーザーログオフ通知
    

    また、気休め程度ですが、レジストリに以下を追加しています。

    HKEY_CURRENT_USER\Control Panel\Desktop
     AutoEndTasks    -->「1」 
    
     HungAppTimeout  -->「30000」 
    
     WaitToKillAppTimeout  -->「30000」
    

    イベントID:1074が発行された後、OSのシャットダウンプロセスの開始を遅延させる方法があれば

    もっと確実にバッチを実行させられそうなのですが、もし何かそのような方法をどなたかご存じでしたら

    ご教示頂けますと幸いです。

    宜しくお願いいたします。

    0 件のコメント コメントはありません