シャットダウン時にウイルスチェックを実行する、あるいはデータのバックアップを取得するといった自動化処理は、Windowsのシャットダウンスクリプトで実現するのが簡単な実装方法です。そのスクリプトの実行が10分以内に完了するものであれば、何の問題もありません。しかし、15分や20分以上の長い時間がかかるものについては、Windowsに古くから存在するバグ(仕様?)に阻まれるかもしれません。
この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
何かネタ、いや未解決のユーザーの困りごとはないかと、Microsoftのユーザーフォーラムをたまにチェックしていますが、先日、「Windows 10のシャットダウンスクリプトが22分で終了してしまうのはなぜか」という質問を目にしました。
バックアップコマンドラインツール「WBADMIN」を利用してシャットダウンと同時にバックアップを開始し、終了後に電源をオフにすることを実現したいようなのですが、適切に設定しているのにもかかわらず、22分経過すると電源がオフになってしまうというのです。無限に実行が完了しない簡単なバッチでも、やはり22分で終了してしまうそうです。
シャットダウンスクリプトが実行を強制停止するまで待機時間は、システムの既定で「10分(600秒)」です。この待機時間は、次のポリシー設定を有効化し、秒数を指定することで調整できます。フォーラムの質問者は既にこの設定を行っており、長い秒数や「0(スクリプトが終了するまで待つ)」にしても期待通りに動作してくれません。
問題が再現性のあるものかどうか、無限ループで時刻や経過時間をファイルにリダイレクトする簡単なスクリプトをシャットダウンスクリプトに仕込んで実際に試してみました。「グループポリシースクリプトの最大待機時間を指定する」が未構成の場合、Windowsの仕様通り、既定の「10分(600秒)」でスクリプトは強制終了されます(画面1)。
しかし、「グループポリシースクリプトの最大待機時間を指定する」を有効にして、「60分(3600秒)」や「0(スクリプトが終了するまで待つ)」に設定した場合、確かに22〜23分で強制終了されてしまいました(画面2)。
シャットダウンスクリプトを1秒ごとに経過秒数を出力するPowerShellスクリプトやバッチ(「Windows XP」の場合は「timeout」コマンドや「start-sleep」コマンドが使えないため短いサイクルで時間を出力させました)に変えて、Windowsの幾つかのバージョンで検証してみました。
「グループポリシースクリプトの最大待機時間を指定する」を「1800秒」で計測したところ、「Windows 10」および「Windows Server 2016」以降ではばらつきがあるものの1400秒(約23分)前後(画面3)、「Windows 7」や「Windows 8.1」は900秒弱で強制終了されました(画面4)。そして、Windows XPは期待(仕様)通り、1800秒(30分)間スクリプトの実行が継続されました(画面5)。
Windowsのバージョン | シャットダウンスクリプトの実行時間 |
---|---|
Windows 10、Windows Server 2016、Windows Server 2019 | 1400秒前後 |
Windows 7 SP1、Windows 8.1 | 900秒弱 |
Windows XP SP3 | 1800秒(正常) |
Windows XPまでは期待通りに動き、Windows 7から900秒(15分)で終了するようになってしまったということを頼りにインターネットを検索してみると、TechNetフォーラムのアーカイブに正にWindows 7のこの問題と対処方法が示されていました。
「Group Policy Client(gpsvc)」サービスが持つ90万(900000)ミリ秒という別のタイムアウトが影響して、15分でシャットダウンスクリプトが強制終了されてしまうそうです。「Group Policy Client(gpsvc)」サービスはWindows XPには存在せず、「Windows Vista」で初めて登場しました。おそらく、Windows Vistaにもシャットダウンスクリプトが900秒(15分)で終了する問題が存在するのでしょう。
Windows 10やWindows Server 2016以降の「イベントログ」(システムログ)を確認したところ、シャットダウンスクリプトからの出力が終了したすぐ後に、イベントID「7043」、ソース「Service Control Manager」、説明「Group Policy Clientサービスは、プレシャットダウンコントロールを受け取った後に正しくシャットダウンされませんでした」のエラーイベントが記録されていました(画面6)。
900秒と1400秒の違いありますが、現在のWindowsにも同じ問題があると予想しました。先に言ってしまうと、上記のアーカイブの対処方法でこの問題は解消できます。待機時間の違いは、Windows 10で行われたシャットダウン処理における何らかの変更の影響でしょう。
「Group Policy Client(gpsvc)」サービスのタイムアウトは、以下のレジストリ値で調整可能です。既定値は現在のWindowsのバージョンでも「900ミリ秒」のままです。このデータを十分に長いミリ秒(最大0xffffffff、10進数で4294967295)に変更することで、最大待機時間より前にシャットダウンスクリプトが強制終了されるのを防止できます。
しかし、このレジストリ値は簡単には変更できません。なぜなら、フルコントロール権限を持つのは「SYSTEMアカウント」だけだからです。管理者であっても、データを変更することや、アクセス許可を変更することはできません。
そんなときに便利なのが、Windows Sysinternalsの「psexec」ユーティリティー(https://docs.microsoft.com/en-us/sysinternals/downloads/psexec)です。
管理者として開いたコマンドプロンプトまたはPowerShellウィンドウで、psexecを以下のように実行することで、SYSTEMアカウントとして「レジストリエディター」(Regedit.exe)を起動して、レジストリを編集することが可能です(画面7)。
psexec -s -i regedit.exe
変更内容は次回のシャットダウン(または再起動)から有効です。筆者は、PreshutdownTimeout値に最大の「4294967295」を設定し、「グループポリシースクリプトの最大待機時間を指定する」に「1800秒」「3600秒」「0」(完了するまで待つ)を設定してみて、それぞれ期待通りに動作することを確認しました(画面8)。
岩手県花巻市在住。Microsoft MVP:Cloud and Datacenter Management(2020-2021)。SIer、IT出版社、中堅企業のシステム管理者を経て、フリーのテクニカルライターに。Microsoft製品、テクノロジーを中心に、IT雑誌、Webサイトへの記事の寄稿、ドキュメント作成、事例取材などを手掛ける。個人ブログは『山市良のえぬなんとかわーるど』。近著は『Windows版Docker&Windowsコンテナーテクノロジ入門』(日経BP社)、『ITプロフェッショナル向けWindowsトラブル解決 コマンド&テクニック集』(日経BP社)。
Copyright © ITmedia, Inc. All Rights Reserved.