syghの新フラグメント置き場

プログラミングTipsやコード断片の保管場所です。お絵描きもときどき載せます。

Windows Updateとの戦い(2018年春の陣、休止状態解除の亡霊)

Windows 10 1703にて、2018-04-18にいくつかのセキュリティアップデートを適用したら、勝手にWindowsの休止状態 (hibernation) が解除されて復帰する(PC電源が勝手に入る)問題が多発するようになりました。休止状態はメモリ内容をストレージに保存してPC電源を落とすので、スリープよりも復帰に時間がかかりますが、休止中に停電が発生しても復帰ができるというメリットがあるので、就寝前にいつも使っています。

以前、休止状態の解除が頻発して困っていたときに、キーボードやマウス、ネットワークアダプターが原因かもしれないと思って、デバイスマネージャーにて[このデバイスで、コンピューターのスタンバイ状態を解除できるようにする]のチェックをすべて外していたので、これらのデバイスが原因である可能性は最初から除外しました。

まず、コマンドプロンプトを管理者権限で起動*1し、powercfgコマンドで前回の復帰の理由を調べます。

Microsoft Windows [Version 10.0.15063]
(c) 2017 Microsoft Corporation. All rights reserved.

C:\WINDOWS\system32>powercfg -lastwake
スリープ状態の解除履歴カウント - 1
スリープ状態の解除履歴 [0]
  スリープ状態の解除元カウント - 1
  スリープ状態の解除元 [0]
    種類: スリープ解除タイマー
    所有者: [SERVICE] \Device\HarddiskVolume2\Windows\System32\svchost.exe (SystemEventsBroker)
    所有者によって示された理由:

イベントビューアーのシステムログで「Power-Troubleshooter」を検索すると、以下のレコードが2018-04-20 05:35:00に記録されていました。

システムは低電力状態から再開しました。

スリープ時間: 2018-04-19T16:44:22.759254000Z
スリープ解除時間: 2018-04-19T20:34:53.450160600Z

スリープ状態の解除元: タイマー - svchost.exe

「スリープ解除タイマー」とは何者でしょうか? 調べてみると電源オプションで無効化できるそうです。

[コントロール パネル] > [ハードウェアとサウンド] > [電源オプション]にて、現在選択されている電源プランの[プラン設定の変更] > [詳細な電源設定の変更]をクリック。
[電源オプション]ダイアログで、[スリープ] - [スリープ解除タイマーの許可]が[有効]になっていました。コイツを[無効]に変更して[OK]または[適用]ボタンをクリック。

これで一安心……と思いきや、やはり休止状態が勝手に解除されてしまいました。

もう一度powercfgとイベントビューアーで調べます。

Microsoft Windows [Version 10.0.15063]
(c) 2017 Microsoft Corporation. All rights reserved.

C:\WINDOWS\system32>powercfg -lastwake
スリープ状態の解除履歴カウント - 1
スリープ状態の解除履歴 [0]
  スリープ状態の解除元カウント - 0

イベントログには2018-04-21 04:38:25に記録があります。

システムは低電力状態から再開しました。

スリープ時間: 2018-04-20T17:57:22.602822200Z
スリープ解除時間: 2018-04-20T19:38:20.464928200Z

スリープ状態の解除元: 不明

はい原因不明でした。

UpdateOrchestratorタスクグループ

タスクスケジューラで確認したところ、UpdateOrchestratorのRebootタスクが指定日時をトリガーとして登録されていました。
UpdateOrchestratorはWindows Updateに関わるタスクグループらしく、スリープや休止状態の勝手な解除を発生させる諸悪の根源です。UpdateOrchestratorを組み込んだMSのエンジニアは、本当に頭のおかしいキチガイでしょう。Windows 8.1からWindows 10に更新した後、しょっちゅうコイツに悩まされていましたが、ここ最近は小康状態だったので油断していました。1703でWindows Updateによる再起動前のリマインダーや、更新の一時停止(最大35日間)をできる機能が追加されたので、再起動の回数自体も減っていました。
ひとまずRebootタスクの[条件]にて、[タスクを実行するためにスリープを解除する]のチェックを外しておきましたが、次回のWindows Update後にはまた勝手に復活していることでしょう。なお、1709ではこの設定がUIから変更できなくなっているそうです。ユーザーにさらなる不自由を強いるとは許せませんね*2

しかし、UpdateOrchestratorのRebootタスクを修正しても、やはり休止状態が勝手に解除されてしまいました。解除元は相変わらず不明です。

WindowsUpdateタスクグループ

WindowsUpdateのAutomatic App Updateタスク*3およびScheduled Startタスクを修正すると改善されるとの情報あり。前者は4時間ごとに無期限に繰り返すよう設定されていました。後者は指定日時をトリガーとして登録されていました。
しかし、[タスクを実行するためにスリープを解除する]はともにチェックが外れていました。
ほかに、AUSessionConnectというタスクも登録されており、これは[タスクを実行するためにスリープを解除する]にチェックが入っていました。
ひとまずAutomatic App UpdateタスクとAUSessionConnectタスクを無効化しておきました。Scheduled Startタスクは無効化しても、一定時間経つと勝手に有効化されるようです。なお、AUSessionConnectは[タスクを実行するためにスリープを解除する]のチェックを外して[OK]をクリックしても、なぜか以下のようなメッセージが表示されて、変更を反映できません。

---------------------------
タスク スケジューラ
---------------------------
タスク スケジューラ サービスが利用できません。タスク スケジューラはサービスへの再接続を試行します。
---------------------------
OK
---------------------------

しかし、Automatic App UpdateタスクとAUSessionConnectタスクを修正・無効化しても、やはり休止状態が勝手に解除されてしまいました。解除元は相変わらず不明です。

powercfgコマンドを使って、スリープ解除元のデバイスとタイマーを列挙してみます。

Microsoft Windows [Version 10.0.15063]
(c) 2017 Microsoft Corporation. All rights reserved.

C:\WINDOWS\system32>powercfg -devicequery wake_armed
NONE

C:\WINDOWS\system32>powercfg -waketimers
[SERVICE] \Device\HarddiskVolume2\Windows\System32\svchost.exe (SystemEventsBroker) によって設定されたタイマーは 04:33:06 (2018-04-24) で有効期限が切れます。
  理由:

バイスは案の定存在しませんでしたが、タイマーが存在するようです。しかし「理由」が分からないのでタスクの特定ができません。

Windowsのタスクキャッシュ

Windowsの各タスクの設定情報自体は "%WinDir%/System32/Tasks" 配下にXMLファイル(拡張子は無し)の形で保存されていますが、レジストリ "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Schedule\TaskCache" 上にもバイナリキャッシュが保存されているようです。またキャッシュのほうが優先されるらしく、XMLファイルを直接編集&保存してWindowsを再起動しても変更内容が反映されません。タスクスケジューラのUIによる変更を確定しようとしたときにエラーとなるのは、おそらくキャッシュが破損しているからではないかと推測されます(4月のWindows Updateで破損した?)。しかしレジストリエディターでキャッシュを削除しようとしても、タスクスケジューラのサービスによってロックされているらしく、削除操作が拒否されます。また、タスクスケジューラのサービスはユーザーが停止させることができません。

セーフモードで起動してキャッシュを消そうかとも考えましたが、いい加減疲れたので、休止状態の勝手な復帰現象の原因追及はひとまずここまでとします。結局、休止状態にした後はPC電源スイッチを切る(|→○)という原始的な方法で対処することにしました。電源スイッチのあるオーソドックスな自作デスクトップ機でよかった。

もう少し追跡してみます。Tasksフォルダー配下のすべてのファイルを対象に、

<WakeToRun>true</WakeToRun>

をグローバル検索してみたところ、前述のAUSessionConnect以外にいくつか引っかかりました。

rempl\shellUpdateOrchestrator\AC Power Downloadはタスクが有効(準備完了)になっていたので、前者は[タスクを実行するためにスリープを解除する]のチェックを外し、後者は無効化しました。それ以外はすでに無効になっているので放置することにします。

Microsoft Windows [Version 10.0.15063]
(c) 2017 Microsoft Corporation. All rights reserved.

C:\WINDOWS\system32>powercfg -waketimers
システムにアクティブなスリープ解除タイマーがありません。

ようやくタイマーがなくなりました。ひとまずこれで様子見とします。

グラフィックスドライバーの勝手な更新

休止状態の解除問題とは直接の関係はありませんが、Windows Updateの履歴を見ると、2018-01-21に、NVIDIA GeForceドライバーが384.94から388.13に許可なく勝手に更新されていました。グラフィックスドライバーは特に相性問題を起こしやすく、たいていのパワーユーザーはドライバーの更新に慎重になるのですが、これが勝手に更新されるとなるとかなり困ります。以前はデバイスドライバーの更新に関してはオプショナル(任意)だったはずなのですが……
ひとまずグループポリシーでデバイスドライバーの更新を無効化する([Windows Updateからドライバーを除外する]を[有効]に構成する)ことで対処しました。

Windows 10更新アシスタントの無限復活

3月頃には「Windows 10更新アシスタント」が勝手にインストールされて、1709のダウンロードが始まる事案が発生しました。更新アシスタントはコントロールパネルで削除しても無限に復活する、まさにゾンビのように厄介なアプリです。グループポリシーでは無効化できず、以下のサイトを参考にしてようやく抑制できました。
www.atmarkit.co.jp

MSはどうしても1709の導入ベースを増やしたがっているようですが、だからといってユーザーの許可なく勝手にアプリをインストールするなんて破廉恥極まりないですね。年2回の大型アップデートスケジュールも、無理やりスケジュールを守ろうとして品質の確保ができなくなってしまっているのが目に見えています。機能追加のためのアップデートとスケジュールではなく、スケジュール遵守のための無理な機能開発になってしまっていて、目的と手段が完全に入れ替わってしまっていますね。お粗末としか言いようがないです。そもそも大型アップデートにより追加あるいは削除される機能のうち、大半は誰も望んでいない変更です。しかも新機能はことごとくオプトアウトなのも始末が悪いです(余計な機能がデフォルトで有効化されていて、無効化するためにはユーザーがいちいち設定を変更しなければならない)。

Windows 10はユーザーの自由と時間と情報と安眠と電気代を奪っている

Windows 8.1までは良くも悪くもエンドユーザーがWindows Updateのタイミングと内容を完全にコントロールすることができていました。翻ってWindows 10では、ユーザーにほとんど自由がありません。せっかく設定を変更して抑制しても、Windows Updateを適用すると(MSにとって都合のいいように)設定が毎回リセットされてしまいます。ましてや、余計な機能てんこ盛りで品質の低い大型アップデートを勝手にインストールして、ユーザーのシステムを台無しにするなんて、犯罪にも等しいです。また、MSは個人情報収集のためには手段を選びません。なりふり構わずあの手この手を使ってきます。知識がないライトユーザーは簡単に騙されて大量に個人情報をぶっこ抜かれてしまうでしょう。こういう汚いことを続けていれば、どんどんパワーユーザーが離れていくということにMSは気付かないんでしょうか。本当に過去最悪のOSです。Windows 10の汚らしい挙動と、MSの下品なゴリ押しのせいで、Direct3D 12*4もUWPも開発に使う気がすっかり消え失せました。開発環境としてずっと慣れ親しんできたWindowsですが、もうウンザリです。もはやWindowsプラットフォーム固有の開発には積極的に投資したくありません。

今のところゲームやクリエイティブツールの関係上、どうしてもWindowsを使わざるを得ない状況ですが、今後Wineの完成度が上がればいずれWindowsを捨ててLinuxに移行したいですね。ソフト電池のような認証ツールもWine環境に対応してくれたらいいのですが。

※2018-06-03追記:
5月度のWindows Updateを実行すると、案の定またスリープ解除タイマーが復活しました。例のごとくタスクのXMLファイル群をグローバル検索してみると、

というタスクが有効かつWakeToRunがtrueになっていたので、[タスクを実行するためにスリープを解除する]のチェックを外しておきました。

※2018-07-16追記:
6月度のWindows Updateを実行すると、以下のタスクが有効かつWakeToRunがtrueになっていたので、[タスクを実行するためにスリープを解除する]のチェックを外しておきました。Windows Updateのたびにスリープ解除タイマーを復活させやがることが分かったので、そろそろ無効化作業を自動化したいですね。

※2018-08-14追記:
7月度のWindows Updateを実行してみたところ、今回はスリープ解除タイマーを復活させていないようです。

※2018-09-17追記:
8月度のWindows Updateを実行してみたところ、今回はスリープ解除タイマーを復活させていないようです。

*1:余談ですが、最初のカレントディレクトリは通常権限だと「%UserProfile%」で起動する一方、管理者権限だと「%SystemRoot%\System32」で起動しますね。

*2:MSが運営している各種フォーラムには、こういった明らかにユーザーに不利益を強いているMSの姿勢すら擁護する大量のマゾ信者がグルとして涌いていて、本当に気持ち悪いです。

*3:Windowsストアアプリを自動更新するためのタスクらしいです。ところでストアアプリなんていう不自由なもの、誰が好き好んで使うんですか?

*4:Direct3DとHLSLの進化が停滞すると競合のOpenGL/VulkanとGLSLも停滞することが予想されるので、Direct3Dの更新自体は続けて欲しいのですが、個人的には今後Direct3D/MetalよりもVulkanのほうが普及率が高くなり、API統一が進むのではないかと予想しています。