\ 最大8%ポイントアップ! / 詳細を見る

[3つの対応方法]Windows Update エラー:KB5034441 – 0x80070643

私が所持している複数のWindows 10 パソコンで同じエラーが発生しました。

まず結論から書くと、大半のパソコンにはインストールする必要のない更新プログラムです。

2024年3月現在、この更新プログラムをどうしてもインストールしたい場合、いくつかの手法で対応できますが、
ある程度パソコンの知識とスキルが必要な対応となります。

  • どのような目的の更新プログラムか?
  • エラーが発生した原因は?
  • 現時点の対応方法は?

など調べて検証した事をまとめました。

 

この記事はこんな方にオススメ!

  • Windows 10 ユーザーの方
    (Windows 11では発生しません)
     
  • 更新プログラム「KB5034441」でエラー“0x80070643”が発生した方
     
  • 更新プログラムの情報やエラーの原因、対応方法を知りたい方
目次

事象

2024年1月、Windows 10 Pro で Windows Updateを実施するも、エラーが発生しました。

Windows Update で 更新プログラム「KB5034441」でエラー“0x80070643”が発生
画像:Windows Update で 更新プログラム「KB5034441」でエラー“0x80070643”が発生

詳しく内容を確認すると、更新プログラム「KB5034441」でエラー“0x80070643”というエラー発生していることを確認。

Windows Update で 更新プログラム「KB5034441」でエラー“0x80070643”が発生(更新履歴より)
画像:Windows Update で 更新プログラム「KB5034441」でエラー“0x80070643”が発生(更新履歴より)

エラー発生した直後の対応は、もう一度更新してみたり、システムドライブをクリーンナップしてからリトライしたり、トラブルシューティングを実施してからリトライなどを試しましたが、いずれの方法も解決できませんでした。
(詳細な対応方法は後述しています。)

調査内容

更新プログラム「KB5034441」とは

実行中の PC 上の Windows 回復環境 (WinRE) に Safe OS 動的更新 (KB5034232) を自動的に適用し、攻撃者がWinREを使用してBitLocker暗号化をバイパスできる可能性があるセキュリティの脆弱性に対処します。詳細については、CVE-2024-20666 を参照してください。

引用元:KB5034441: Windows Recovery Environment update for Windows 10, version 21H2 and 22H2: January 9, 2024

つまりは、WinRE(回復パーティション)のセキュリティ強化のため、更新プログラム「 KB5034232 」を導入する事を目的とした更新プログラムということです。

KB5034441で修正するセキュリティの脆弱性「CVE-2024-20666」とは

こちらの公式文書を確認し要約してみると、

Windows OSのBitLocker機能でハードディスクのセキュリティを強化している場合、 WinREの脆弱性をつき、BitLockerの保護機能をすり抜けて攻撃される可能性がある問題。

ということがわかりました。

“KB5034441”を適用するべき環境

今回エラーになった更新プログラムは「 Windows 10用に提供 」されています。
また、更新プログラムの中身は「 BitLocker(ビットロッカー) 」というWindows 標準機能 でディスクの暗号化機能をオンにしている環境(デフォルトはオフ)のみ関わる内容。

なお、BitLockerがオンの環境で問題が発生しうるということですが、更新プログラム自体は、BitLockerがオフの環境にも配布される更新プログラムです。
(現時点、設定がオフでも将来的にオンとする可能性があるため、配布していると思われる。)

以上のことをふまえると、「 下記の条件に該当する環境のみ、この更新プログラムを適用する必要がある 」と言えます。

  • 条件1:対象のWindows バージョンであること
    このバージョンのWindows環境のみ、更新プログラムが配布されています。
    • Windows 10 Version 22H2
    • Windows 10 Version 21H2
       
  • 条件2:Windows 10 でBitLockerを有効化できるエディションであること
    下記にWindows 10 のエディション毎、BitLockerを設定できるか有無を記載。

    :Windows 10 Home
    :Windows 10 Sモード
    :Windows 10 Pro
    :Windows 10 Enterprise
    :Windows 10 Education
    :Windows 10 Pro Education/SE
     
    参考情報:Windows 10 の エディション – Wikipedia
    参考情報:BitLockerの対象エディションと有効化可能なライセンスについて
     
  • 条件3:現在、BitLockerを有効にしていること、または今後有効にする予定があること
     

前述した通り、Windows 10 において BitLocker機能は規定でオフとなっているので、
条件3に該当する環境はかなり少ないのではないでしょうか。

逆にこの更新プログラムを適用しなくても良い環境は、 BitLocker機能を使用していない、もしくは使用する予定がない 環境です。
この環境の場合、更新プログラム「 KB5034441 」がエラーとなりインストールできなくてもセキュリティーリスクが発生しないということになります。

環境の条件を確認する方法

上記の条件で記載した Windows のバージョン と エディション の確認方法BitLockerの設定状態を確認する方法 を紹介します。

しらたま

ヒント:開閉できるエリア

下記のようなエリアはクリックすると開閉可能っピ 👍

Windows の バージョン と エディション を確認する方法

画面で確認する方法(GUI)

STEP
⊞ Windowsキー + R 」で“ファイル名を指定して実行”を起動
STEP
ms-settings:about 」で設定画面、システムの詳細情報が開く
ms-settings:about
STEP
表示されたページの「 Windows の仕様 」で“エディション”を確認

詳細情報のページが開くので、中腹ぐらいまでスクロールし、
項目「 Windows の仕様 」に記載されている“エディション” と “バージョン” を確認。

Windows の仕様にて、エディションが「Pro」。バージョンが「22H2」。
画像:この画面ではエディションが「Pro」。バージョンが「22H2」となる

補足情報:コマンドで確認したい方はコチラ

コマンドで確認する方法(CLI – PowerShellコマンドレット)

STEP
⊞ Windowsキー + R 」で“ファイル名を指定して実行”を起動
STEP
“ファイル名を指定して実行”で「 powershell 」と入力
STEP
Ctrl + Shift + Enterキー 」でPowerShellウィンドウを管理者として実行
STEP
2種類のPowerShellコマンドレットを実行
PS C:\WINDOWS\system32> Get-WindowsEdition -Online


Edition : Professional



PS C:\WINDOWS\system32>
PS C:\WINDOWS\system32> Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" | Select-Object DisplayVersion

DisplayVersion
--------------
22H2


PS C:\WINDOWS\system32>

BitLockerの設定を確認する方法

画面で確認する方法(GUI – マウス操作編)

STEP
スタートメニュー内、フォルダー「 Windows システム ツール」 の中にある「 コントロールパネル 」をクリック
STEP
コントロールパネルの “システムとセキュリティ” を選択

※ コントロールパネルの表示方法:カテゴリの場合

STEP
“システムとセキュリティ”一覧から「 BitLocker ドライブ暗号化 」をクリック
STEP
“BitLocker ドライブ暗号化”が開く
STEP
各ドライブでBitLockerが有効か無効か確認

ひとつでもBitLockerが有効となっている場合、この更新プログラムの適用が必要です。

Cドライブ Dドライブ Gドライブのすべて BitLocker 無効な状態
画像:この画面ではCドライブ・Dドライブ・GドライブのすべてでBitLockerが無効な状態

補足情報:その他のGUI確認方法 や コマンドで確認したい方はコチラ

画面で確認する方法(GUI – “ファイル名を指定して実行”を使用)

STEP
⊞ Windowsキー + R 」で“ファイル名を指定して実行”を起動
STEP
“ファイル名を指定して実行”で「 control /name Microsoft.BitLockerDriveEncryption 」と入力しEnterキーを押す
STEP
“BitLocker ドライブ暗号化”が開く
STEP
各ドライブでBitLockerが有効か無効か確認

ひとつでもBitLockerが有効となっている場合、この更新プログラムの適用が必要です。

Cドライブ Dドライブ Gドライブのすべて BitLocker 無効な状態
画像:この画面ではCドライブ・Dドライブ・GドライブのすべてでBitLockerが無効な状態

コマンドで確認する方法(CLI – PowerShellコマンドレット)

STEP
⊞ Windowsキー + R 」で“ファイル名を指定して実行”を起動
STEP
“ファイル名を指定して実行”で「 powershell 」と入力
STEP
Ctrl + Shift + Enterキー 」でPowerShellウィンドウを管理者として実行
STEP
PowerShellコマンドレット「 Get-BitLockerVolume 」を実行

下記、実際に実行した結果を例に説明すると、項目「 ProtectionStatus 」の状態で確認できます。

  • 結果が On であれば、BitLockerが有効な状態
  • 結果が Off であれば、BitLockerが無効の状態
PS C:\WINDOWS\system32> Get-BitLockerVolume


   ComputerName: "コンピューター名"

VolumeType      Mount CapacityGB VolumeStatus           Encryption KeyProtector              AutoUnlock Protecti
                Point                                   Percentage                           Enabled    onStatus
----------      ----- ---------- ------------           ---------- ------------              ---------- --------
Data            G:        465.76 FullyDecrypted         0          {}                                   Off
OperatingSystem C:        130.34 FullyDecrypted         0          {}                                   Off
Data            D:        106.35 FullyDecrypted         0          {}                                   Off


PS C:\WINDOWS\system32>

原因

冒頭で説明している更新プログラムの公式文書には、下記のような記述が追記されました。
(私が最初にこのエラーを確認した2024年1月時点、エラーに関する記載はなかったと記憶しています。
 おそらく、エラーの報告が数多くあがり対応されたのでしょう。)

重要

このアップデートを正常にインストールするには、回復パーティションに 250 MB の空き領域が必要です。回復パーティションに十分な空き領域がない場合、この更新は失敗します。この場合、次のエラー メッセージが表示されます。

0x80070643 – ERROR_INSTALL_FAILURE

このエラーを回避するか、この障害から回復するには、 手順に従ってパーティションのサイズを手動で変更し、WinRE 更新プログラムをインストールして から、この更新プログラムのインストールを試してください。

または、サンプル スクリプトを使用して WinRE 回復パーティションのサイズを増やすには、「 Windows RE パーティションの拡張 」を参照してください。

引用元:KB5034441: Windows Recovery Environment update for Windows 10, version 21H2 and 22H2: January 9, 2024

エラーの原因は、「 回復パーティションの空き領域が 250 MB 以上ない環境で発生 」との事。

私はWindows 10 OSの環境を複数台、所持しています。それらほぼ全ての環境において、回復パーティションの空き領域が 250 MB よりも小さく条件と合致し、今回のWindows Updateのエラーも発生しました。

ただ、限られた少数の環境ではありますが、回復パーティションの空き領域が 250 MB 以上の環境でも、
エラーが発生
しました。
(回復パーティションの空き領域は、約500 MB でした。)

この例外的な環境の対応では、Windows 11 にアップグレードしたことで問題が解決しています。
(詳しい対応方法は後述)

参考情報:Windows における パーティションの概要

上記の公式文書をみると、回復パーティションの総容量は通常、500 ~ 700 MB とのこと。

エラーが発生した環境は、ほぼディスクの総容量が少ない仮想環境で発生していました。

おそらくWindows OS がインストールされている ディスクの総容量が少なく、
それに比例し回復パーティションも自動的に小さく設定されているのでしょう。

今回のエラーは リソースを必要最低限、小さく設定しているであろう仮想環境で発生しやすいエラー という事が言えます。

対応方法

2024年3月現在、おおきくわけて3つの対応方法があります。
いずれかの方法を対応することでエラーを消すことができます。

3つの対応はそれぞれ別の環境を使って検証済み

こちらで3つの対応方法を紹介していますが、それぞれ別の環境を使って検証し、このエラーが解消できました。
ご自身にとって、どの対応方法が適切か検討した上でご対応ください。

私が個人的にオススメしているのは対応1 の 「エラーが発生している更新プログラムを一時的に非表示にする方法」です。

  1. 対応1.エラーが発生している更新プログラムを一時的に非表示にする方法
    私のWindows 10 環境だけでも、かなりの環境でエラーが発生しました。

    世界的にみても、最新の Windows 11 よりも Windows 10 の方がシェア率が高く(調査:statcounter調べ)、
    ネットで検索してもエラーが発生した事例がかなり多いようです。

    2024年3月現在で公式が公開している対応方法は、1つがコマンドプロンプトを使った対応方法で、
    もう1つがPowerShellスクリプトを作成し実行する対応方法です。

    これらの対応方法は、ある程度パソコンの知識とスキルが必要な作業となり、一般のユーザーは対応できません。
    一部のユーザーのみが対応できる方法となる為、位置づけとしては暫定的な対応の分類だと思われます。

    また、繰り返しになりますが、BitLockerを有効にしていなければ問題のない脆弱性の問題

    更新プログラムの差し替えなど、Microsoftの正式な対応方法を待つのが得策です。
    対応方法として、エラーが発生している更新プログラムを一時的に非表示にする方法を後述します。
     
  2. 対応2.回復パーティションを拡張して更新プログラムを導入する方法
    この方法は、公式から周知されている方法 や ネットで出回っている方法 など、この中でもいくつか手法があります。
     
    対応2-1 手動でパーティションの拡張を行う方法(Microsoft公式の手順その1)
    対応2-2 PowerShellスクリプトでパーティションを拡張する方法(Microsoft公式の手順その2)
    対応2-3 WinREを再構成する方法
     
    私が実際に試して有効だった2つの方法を後述。
     
  3. 対応3.Windows 11 にアップグレードする方法
    “Windows 10 に該当する問題なのであれば、Windows 11 にアップグレードしちゃえばいいじゃない。”という思考でこの方法を試しました。

    私の環境ではうまくいきましたが、すべての環境でうまくいくかはわかりません。
    そもそもシステム要件的にアップグレードできないという環境もありますね。

    また、アップグレードは、リスクの高い作業となるため、必要に応じてシステムバックアップを取得するなど、
    万全を期して対応することをオススメします

    私の環境で問題なくアップグレードできた際の手順を後述します。

対応1.エラーが発生している更新プログラムを一時的に非表示にする方法

この手順により、Microsoft の正式な対応方法が提示されるまでエラー表示を消すことができます。
BitLockerを有効にしなければ、非表示のままで問題ないですが、
作業後、この更新プログラムを非表示にしたことを忘れないようにメモしておきましょう。

この更新プログラムを非表示にする方法は、別記事として作成中となります。
作成後、こちらにリンクを貼ろうと思います。

2024年3月29日 記事の作成が完了。下記の記事をご参照ください。

補足情報:上記で紹介している記事を参考に更新プログラムを非表示してみた。

作業手順のポイントになる部分を抜粋して紹介。

STEP
作業前は Windows Update でエラーが表示されていること
Windows Updateでエラーが表示されている状態
画像:Windows Updateでエラーが表示されている状態
STEP
ツールの非表示モード(Hide updates)にて対象の「 KB5034441 」を選択
KB5034441を非表示とする
画像:KB5034441を非表示とする
STEP
問題なく非表示の処理が終わったこと
非表示が問題なく終わったこと
画像:非表示が問題なく終わったこと
STEP
作業後は Widows Updateでエラーが消えたこと
エラーが発生した更新プログラムが非表示になったこと
画像:エラーが発生した更新プログラムが非表示になったこと

対応2.回復パーティションを拡張して更新プログラムを導入する方法

この中でもいくつかの方法があります。私が試した内容は下記の3点です。

  • 対応2-1.手動でパーティションの拡張を行う方法(Microsoft公式の手順その1)
    こちらの記事で方法を公開中。
     
    👍 公式からの手順ということもあり、個人的にはこの方法が一番オススメ。
     
  • 対応2-2.PowerShellスクリプトでパーティションを拡張する方法(Microsoft公式の手順その2)
    こちらの記事で方法を公開中。
     
    ここで紹介されているPowerShellスクリプトは、実行するための制約が多すぎて使い物になりませんでした。
    👎 オススメできない対応方法です。
     
  • 対応2-3.WinREを再構成する方法
    こちらの記事で方法を公開中。
     
    この更新プログラムに対するMicrosoft公式の方法ではありませんが、対応可能な方法でした。
    また、この記事は更新プログラムが配信されて初期にやりとりされていたMicrosoft Comminutyでの情報を参考にされていると思われます。

このうち、実績のある「 対応2-1の手動でパーティションの拡張を行う方法 」と 「 対応2-3のWinREを再構成する方法 」を紹介。

しらたま

ヒント:開閉できるエリア

下記のようなエリアはクリックすると開閉可能っピ 👍

対応2-1.手動でパーティションの拡張を行う方法

下記、公式の記事で紹介している内容をココでより詳しく手順を解説していきます。

STEP
“ディスクの管理”で事前のパーティション構成を確認
STEP
コマンドプロンプトを管理者権限で実行

ファイル名を指定して実行で「cmd」と入力。つづいて「 Ctrl + Shift + Enterキー 」でコマンドプロンプトを管理者権限で実行する。

  • 公式でもコマンドプロンプトを起動していますが、この手順をPowerShellに置き換えて実行しても問題ありません。
STEP
WinREサービスが起動中である事を確認

Windows REの状態が「 Enabled 」となり起動中であることを確認する。

reagentc /info
C:\WINDOWS\system32>reagentc /info
Windows 回復環境 (Windows RE) およびシステム リセット構成
情報:

    Windows RE の状態:         Enabled
    Windows RE の場所:         \\?\GLOBALROOT\device\harddisk1\partition5\Recovery\WindowsRE
    ブート構成データ (BCD) ID: 3604668f-249b-11eb-a108-999157d203d8
    回復イメージの場所:
    回復イメージ インデックス: 0
    カスタム イメージの場所:
    カスタム イメージ インデックス: 0

REAGENTC.EXE: 操作は成功しました。


C:\WINDOWS\system32>
STEP
WinRE を停止する
reagentc /disable
C:\WINDOWS\system32>reagentc /disable
REAGENTC.EXE: 操作は成功しました。


C:\WINDOWS\system32>

reagentc /info
C:\WINDOWS\system32>reagentc /info
Windows 回復環境 (Windows RE) およびシステム リセット構成
情報:

    Windows RE の状態:         Disabled
    Windows RE の場所:
    ブート構成データ (BCD) ID: 00000000-0000-0000-0000-000000000000
    回復イメージの場所:
    回復イメージ インデックス: 0
    カスタム イメージの場所:
    カスタム イメージ インデックス: 0

REAGENTC.EXE: 操作は成功しました。


C:\WINDOWS\system32>
STEP
Windows ディスク管理ツール「diskpart」を起動
diskpart
C:\WINDOWS\system32>diskpart

Microsoft DiskPart バージョン 10.0.19041.3636

Copyright (C) Microsoft Corporation.
コンピューター: "コンピューター名"

DISKPART>
STEP
ディスクの一覧を表示
list disk
DISKPART> list disk

  ディスク      状態           サイズ   空き   ダイナ GPT
  ###                                          ミック
  ------------  -------------  -------  -------  ---  ---
  ディスク 0    オンライン           465 GB  1024 KB
  ディスク 1    オンライン           238 GB    12 MB        *

DISKPART>

私の環境では、ディスクが2枚あります。

STEP
システムドライブがインストールされているディスク番号を選択
sel disk 1
DISKPART> sel disk 1

ディスク 1 が選択されました。

DISKPART>

私の環境では、「 ディスク1 」にWindows OSがインストールされています。
 

どのディスクにインストールされているか不明な方は、いずれかのディスクを選択した後、
list part 」コマンドで、Cドライブ(規定の場合)があるか確認してください。

これらコマンドは、ただディスクを選択(sel = select)しているか。一覧表示(list)で中身を確認しているだけなので、
臆することなくコマンドを実行してみてください。
 

また、冒頭に実行した「 reagentc /info 」の結果でも、Windows OSがインストールされているドライブを判断できます。

私の環境の場合、「 Windows RE の場所: \?\GLOBALROOT\device\harddisk1\partition5\Recovery\WindowsRE 」となっていた為、「 ディスクの1番 の パーティション5番 」に回復パーティションが存在します。
回復パーティションと同じディスクにCドライブがあるので、システムドライブがインストールされているディスクは「 1 」だと判断できます。

STEP
パーティションの一覧を確認
list part
DISKPART> list part

  Partition ###  Type                Size     Offset
  -------------  ------------------  -------  -------
  Partition 1    システム               700 MB  1024 KB
  Partition 2    予約                 128 MB   701 MB
  Partition 3    プライマリ              130 GB   829 MB
  Partition 4    プライマリ              105 GB   131 GB
  Partition 5    回復                 990 MB   236 GB
  Partition 6    回復                1086 MB   237 GB

DISKPART>

以後の作業では、システムドライブを選択するので、直接的に関係のない補足情報ですが、
わたしの環境では、Partition 5 と Partition 6 で2つ回復パーティションがあります。
これは、以前にWindows OS を Windows 7 から Windows 10 にアップグレードした為、
このようなパーティション構成になっています。

前述しているとおり、「reagentc /info」の結果により現在使用中の回復パーティションを確認可能です。
私の環境では、Partition 5 が Windows 10 で使用中の回復パーティション。
Partition 6 にある回復パーティションは、Windows 7 で使用していた回復パーティションです。

STEP
システムドライブ(規定:Cドライブ)のパーティションを選択
sel part 4
DISKPART> sel part 4

パーティション 4 が選択されました。

DISKPART>
STEP
システムドライブの容量を「 250MB 」縮小する
shrink desired=250 minimum=250
DISKPART> shrink desired=250 minimum=250

ボリュームは、次の方法で正常に縮小されました:  250 MB

DISKPART>

パソコンの知識に明るい方であれば、システムドライブでなくてもよいです。総容量に余裕のあるパーティションを選択しなおして縮小してください。

STEP
現在使用中の回復パーティションを選択

同じ環境でずっとWindows アップグレードを実施してる場合、複数回復パーティションがある場合があります。
冒頭に実行した「 reagentc /info 」の結果により、現在どの回復パーティションを使用しているか確認できます。

私の環境の場合、「 Windows RE の場所: \?\GLOBALROOT\device\harddisk1\partition5\Recovery\WindowsRE 」となっていた為、「 ディスクの1番 の パーティション5番 」に回復パーティションが存在します。

sel part 5
DISKPART> sel part 5

パーティション 5 が選択されました。

DISKPART>
STEP
回復パーティションを削除する
delete partition override
DISKPART> delete partition override

DiskPart は選択されたパーティションを正常に削除しました。

DISKPART>
STEP
ディスクの種類を確認
list disk
DISKPART> list disk

  ディスク      状態           サイズ   空き   ダイナ GPT
  ###                                          ミック
  ------------  -------------  -------  -------  ---  ---
  ディスク 0    オンライン           465 GB  1024 KB
* ディスク 1    オンライン           238 GB  1252 MB        *

DISKPART>

システムドライブが入っているディスク1のGPT欄に「 * 」の印がある場合、GPT パーティションである事を確認。
なお、このGPT欄に「 * 」の印がない場合は、MPTパーティションとなる。

ここでの確認結果により、STEP14 の GPTパーティションの手順STEP15 の MPTパーティションの手順 か作業が分岐します。

STEP
(対象ディスクがGPT パーティションだった場合)
STEP 13 ディスクの種類を確認 の結果により対応

STEP 13 で システムドライブがあるディスク番号の行のGPT項目に「 * 」がある場合のみ、本項を対応。

STEP 15 の MPT パーティションだった場合の手順は対応不要。

create partition primary id=de94bba4-06d1-4d40-a16a-bfd50179d6ac
DISKPART> create partition primary id=de94bba4-06d1-4d40-a16a-bfd50179d6ac

DiskPart は指定したパーティションの作成に成功しました。

DISKPART>

gpt attributes =0x8000000000000001
DISKPART> gpt attributes =0x8000000000000001

選択された GPT パーティションに DiskPart で属性を割り当てました。

DISKPART>

次のSTEP15は、MPT パーティションのため、手順を飛ばす。

STEP
(対象ディスクがMPT パーティションだった場合)
STEP 13 ディスクの種類を確認 の結果により対応

STEP 13 で システムドライブがあるディスク番号の行のGPT項目に「 * 」がなく空欄だった場合のみ、本項を対応。

STEP 14 の GPT パーティションだった場合の手順は対応不要。

create partition primary id=27
※ MPT パーティション環境は未検証のため、実際に実行したコマンド結果なし。
STEP
パーティションの書式を設定
format quick fs=ntfs label="Windows RE tools"
DISKPART> format quick fs=ntfs label="Windows RE tools"

  100% 完了しました

DiskPart は、ボリュームのフォーマットを完了しました。

DISKPART>
STEP
新しい回復パーティションが作成されていること
list vol
DISKPART> list vol

  Volume ###  Ltr Label        Fs    Type        Size     Status     Info
  ----------  --- -----------  ----  ----------  -------  ---------  --------
  Volume 0     G   ボリューム        NTFS   Partition    465 GB  正常
  Volume 1     C   OS           NTFS   Partition    130 GB  正常         ブート
  Volume 2     D   ボリューム        NTFS   Partition    105 GB  正常
  Volume 3         ESP          FAT32  Partition    700 MB  正常         システム
  Volume 5         DELLSUPPORT  NTFS   Partition   1086 MB  正常         非表示
* Volume 6         Windows RE   NTFS   Partition   1240 MB  正常         非表示

DISKPART>
STEP
ディスク管理ツール「diskpart」の終了
exit
DISKPART> exit

DiskPart を終了しています...

C:\\WINDOWS\\system32>
STEP
WinREを起動
reagentc /enable
C:\\WINDOWS\\system32>reagentc /enable
REAGENTC.EXE: 操作は成功しました。


C:\\WINDOWS\\system32>

reagentc /info
C:\\WINDOWS\\system32>reagentc /info
Windows 回復環境 (Windows RE) およびシステム リセット構成
情報:

    Windows RE の状態:         Enabled
    Windows RE の場所:         \\\\?\\GLOBALROOT\\device\\harddisk1\\partition5\\Recovery\\WindowsRE
    ブート構成データ (BCD) ID: 36046691-249b-11eb-a108-999157d203d8
    回復イメージの場所:
    回復イメージ インデックス: 0
    カスタム イメージの場所:
    カスタム イメージ インデックス: 0

REAGENTC.EXE: 操作は成功しました。


C:\\WINDOWS\\system32>
STEP
“ディスクの管理”で事後のパーティション構成を確認
STEP
エラーとなっているWindows Update で「再試行」ボタンをクリック
Windows Update エラー画面で再試行ボタンをクリック
画像:Windows Update エラー画面で「再試行ボタン」をクリック
STEP
エラーとなっていたKB5034441が正常にインストールされたことを確認

対応2-3.WinREを再構成する方法

STEP
PowerShellスクリプトの作成

こちらの公式サイトに掲載されているPowerShellのコードより、PowerShellスクリプトファイル(*.ps1)を作成。
なお、保存する際の文字コードは「 UTF-8 」を設定してください。

公式で推奨されているのは、バージョン 2004 以降 の「PatchWinREScript_2004plus.ps1」です。

公式の記事で記載しているとおり、本件のエラーが発生しているKB5034441以外の更新プログラムは全てインストールした後に、
推奨されている「PatchWinREScript_2004plus.ps1」を準備したほうが問題が発生しにくいと思われます。

Windows 10 バージョン 2004 以降:PatchWinREScript_2004plus.ps1

2024年3月現在のコードをコピペ。
空行は正規表現により削除しました。また、インデントも合わせています。

################################################################################################
#
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
#
# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
################################################################################################
Param (
    [Parameter(HelpMessage="Work Directory for patch WinRE")][string]$workDir="",
    [Parameter(Mandatory=$true,HelpMessage="Path of target package")][string]$packagePath
)
# ------------------------------------
# Help functions
# ------------------------------------
# Log message
function LogMessage([string]$message)
{
    $message = "$([DateTime]::Now) - $message"
    Write-Host $message
}
function IsTPMBasedProtector
{
    $DriveLetter = $env:SystemDrive
    LogMessage("Checking BitLocker status")
    $BitLocker = Get-WmiObject -Namespace "Root\cimv2\Security\MicrosoftVolumeEncryption" -Class "Win32_EncryptableVolume" -Filter "DriveLetter = '$DriveLetter'"
    if(-not $BitLocker)
    {
        LogMessage("No BitLocker object")
        return $False
    }
    $protectionEnabled = $False
    switch ($BitLocker.GetProtectionStatus().protectionStatus){
        ("0"){
            LogMessage("Unprotected")
            break
        }
        ("1"){
            LogMessage("Protected")
            $protectionEnabled = $True
            break
        }
        ("2"){
            LogMessage("Uknown")
            break
        }
        default{
            LogMessage("NoReturn")
            break
        }
    }
    if (!$protectionEnabled)
    {
        LogMessage("Bitlocker isn’t enabled on the OS")
        return $False
    }
    $ProtectorIds = $BitLocker.GetKeyProtectors("0").volumekeyprotectorID
    $return = $False
    foreach ($ProtectorID in $ProtectorIds){
        $KeyProtectorType = $BitLocker.GetKeyProtectorType($ProtectorID).KeyProtectorType
        switch($KeyProtectorType){
            "1"{
                LogMessage("Trusted Platform Module (TPM)")
                $return = $True
                break
            }
            "4"{
                LogMessage("TPM And PIN")
                $return = $True
                break
            }
            "5"{
                LogMessage("TPM And Startup Key")
                $return = $True
                break
            }
            "6"{
                LogMessage("TPM And PIN And Startup Key")
                $return = $True
                break
            }
            default {break}
        }#endSwitch
    }#EndForeach
    if ($return)
    {
        LogMessage("Has TPM-based protector")
    }
    else
    {
        LogMessage("Doesn't have TPM-based protector")
    }
    return $return
}
function SetRegistrykeyForSuccess
{
    reg add HKLM\SOFTWARE\Microsoft\PushButtonReset /v WinREPathScriptSucceed_CVE_2024_20666 /d 1 /f
}
function TargetfileVersionExam([string]$mountDir)
{
    # Exam target binary
    $targetBinary=$mountDir + "\Windows\System32\winload.efi"
    LogMessage("TargetFile: " + $targetBinary)
    $realNTVersion = [Diagnostics.FileVersionInfo]::GetVersionInfo($targetBinary).ProductVersion
    $versionString = "$($realNTVersion.Split('.')[0]).$($realNTVersion.Split('.')[1])"
    $fileVersion = $($realNTVersion.Split('.')[2])
    $fileRevision = $($realNTVersion.Split('.')[3])
    LogMessage("Target file version: " + $realNTVersion)
    if (!($versionString -eq "10.0"))
    {
        LogMessage("Not Windows 10 or later")
        return $False
    }
    $hasUpdated = $False
    #Windows 10, version 1507 10240.20400
    #Windows 10, version 1607 14393.6610
    #Windows 10, version 1809 17763.5322
    #Windows 10, version 2004 1904X.3920
    #Windows 11, version 21H2 22000.2710
    #Windows 11, version 22H2 22621.3000
    switch ($fileVersion) {
        "10240" {
            LogMessage("Windows 10, version 1507")
            if ($fileRevision -ge 20400)
            {
                LogMessage("Windows 10, version 1507 with revision " + $fileRevision + " >= 20400, updates have been applied")
                $hasUpdated = $True
            }
            break
        }
        "14393" {
            LogMessage("Windows 10, version 1607")
            if ($fileRevision -ge 6610)
            {
                LogMessage("Windows 10, version 1607 with revision " + $fileRevision + " >= 6610, updates have been applied")
                $hasUpdated = $True
            }
            break
        }
        "17763" {
            LogMessage("Windows 10, version 1809")
            if ($fileRevision -ge 5322)
            {
                LogMessage("Windows 10, version 1809 with revision " + $fileRevision + " >= 5322, updates have been applied")
                $hasUpdated = $True
            }
            break
        }
        "19041" {
            LogMessage("Windows 10, version 2004")
            if ($fileRevision -ge 3920)
            {
                LogMessage("Windows 10, version 2004 with revision " + $fileRevision + " >= 3920, updates have been applied")
                $hasUpdated = $True
            }
            break
        }
        "22000" {
            LogMessage("Windows 11, version 21H2")
            if ($fileRevision -ge 2710)
            {
                LogMessage("Windows 11, version 21H2 with revision " + $fileRevision + " >= 2710, updates have been applied")
                $hasUpdated = $True
            }
            break
        }
        "22621" {
            LogMessage("Windows 11, version 22H2")
            if ($fileRevision -ge 3000)
            {
                LogMessage("Windows 11, version 22H2 with revision " + $fileRevision + " >= 3000, updates have been applied")
                $hasUpdated = $True
            }
            break
        }
        default {
            LogMessage("Warning: unsupported OS version")
        }
    }
    return $hasUpdated
}
function PatchPackage([string]$mountDir, [string]$packagePath)
{
    # Exam target binary
    $hasUpdated =TargetfileVersionExam($mountDir)
    if ($hasUpdated)
    {
        LogMessage("The update has already been added to WinRE")
        SetRegistrykeyForSuccess
        return $False
    }
    # Add package
    LogMessage("Apply package:" + $packagePath)
    Dism /Add-Package /Image:$mountDir /PackagePath:$packagePath
    if ($LASTEXITCODE -eq 0)
    {
        LogMessage("Successfully applied the package")
    }
    else
    {
        LogMessage("Applying the package failed with exit code: " + $LASTEXITCODE)
        return $False
    }
    # Cleanup recovery image
    LogMessage("Cleanup image")
    Dism /image:$mountDir /cleanup-image /StartComponentCleanup /ResetBase
    if ($LASTEXITCODE -eq 0)
    {
        LogMessage("Cleanup image succeed")
    }
    else
    {
        LogMessage("Cleanup image failed: " + $LASTEXITCODE)
        return $False
    }
    return $True
}
# ------------------------------------
# Execution starts
# ------------------------------------
# Check breadcrumb
if (Test-Path HKLM:\Software\Microsoft\PushButtonReset)
{
    $values = Get-ItemProperty -Path HKLM:\Software\Microsoft\PushButtonReset
    if (!(-not $values))
    {
        if (Get-Member -InputObject $values -Name WinREPathScriptSucceed_CVE_2024_20666)
        {
            $value = Get-ItemProperty -Path HKLM:\Software\Microsoft\PushButtonReset -Name WinREPathScriptSucceed_CVE_2024_20666
            if ($value.WinREPathScriptSucceed_CVE_2024_20666 -eq 1)
            {
                LogMessage("This script was previously run successfully")
                exit 1
            }
        }
    }
}
if ([string]::IsNullorEmpty($workDir))
{
    LogMessage("No input for mount directory")
    LogMessage("Use default path from temporary directory")
    $workDir = [System.IO.Path]::GetTempPath()
}
LogMessage("Working Dir: " + $workDir)
$name = "9f8131ee-878f-4525-bf31-e446aac3016a_Mount"
$mountDir = Join-Path $workDir $name
LogMessage("MountDir: " + $mountdir)
# Delete existing mount directory
if (Test-Path $mountDir)
{
    LogMessage("Mount directory: " + $mountDir + " already exists")
    LogMessage("Try to unmount it")
    Dism /unmount-image /mountDir:$mountDir /discard
    if (!($LASTEXITCODE -eq 0))
    {
        LogMessage("Warning: unmount failed: " + $LASTEXITCODE)
    }
    LogMessage("Delete existing mount direcotry " + $mountDir)
    Remove-Item $mountDir -Recurse
}
# Create mount directory
LogMessage("Create mount directory " + $mountDir)
New-Item -Path $mountDir -ItemType Directory
# Set ACL for mount directory
LogMessage("Set ACL for mount directory")
icacls $mountDir /inheritance:r
icacls $mountDir /grant:r SYSTEM:"(OI)(CI)(F)"
icacls $mountDir /grant:r *S-1-5-32-544:"(OI)(CI)(F)"
# Mount WinRE
LogMessage("Mount WinRE:")
reagentc /mountre /path $mountdir
if ($LASTEXITCODE -eq 0)
{
    # Patch WinRE
    if (PatchPackage -mountDir $mountDir -packagePath $packagePath)
    {
        $hasUpdated = TargetfileVersionExam($mountDir)
        if ($hasUpdated)
        {
            LogMessage("After patch, find expected version for target file")
        }
        else
        {
            LogMessage("Warning: After applying the patch, unexpected version found for the target file")
        }
        LogMessage("Patch succeed, unmount to commit change")
        Dism /unmount-image /mountDir:$mountDir /commit
        if (!($LASTEXITCODE -eq 0))
        {
            LogMessage("Unmount failed: " + $LASTEXITCODE)
            exit 1
        }
        else
        {
            if ($hasUpdated)
            {
                if (IsTPMBasedProtector)
                {
                    # Disable WinRE and re-enable it to let new WinRE be trusted by BitLocker
                    LogMessage("Disable WinRE")
                    reagentc /disable
                    LogMessage("Re-enable WinRE")
                    reagentc /enable
                    reagentc /info
                }
                # Leave a breadcrumb indicates the script has succeed
                SetRegistrykeyForSuccess
            }
        }
    }
    else
    {
        LogMessage("Patch failed or is not applicable, discard unmount")
        Dism /unmount-image /mountDir:$mountDir /discard
        if (!($LASTEXITCODE -eq 0))
        {
            LogMessage("Unmount failed: " + $LASTEXITCODE)
            exit 1
        }
    }
}
else
{
    LogMessage("Mount failed: " + $LASTEXITCODE)
}
# Cleanup Mount directory in the end
LogMessage("Delete mount direcotry")
Remove-Item $mountDir -Recurse
Windows 10 バージョン 1909 以前:PatchWinREScript_General.ps1

2024年3月現在のコードよりコピペ。
空行は正規表現により削除しました。また、インデントも合わせています。

################################################################################################
#
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
#
# THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
################################################################################################
Param (
    [Parameter(HelpMessage="Work Directory for patch WinRE")][string]$workDir="",
    [Parameter(Mandatory=$true,HelpMessage="Path of target package")][string]$packagePath
)
# ------------------------------------
# Help functions
# ------------------------------------
# Log message
function LogMessage([string]$message)
{
    $message = "$([DateTime]::Now) - $message"
    Write-Host $message
}
function IsTPMBasedProtector
{
    $DriveLetter = $env:SystemDrive
    LogMessage("Checking BitLocker status")
    $BitLocker = Get-WmiObject -Namespace "Root\cimv2\Security\MicrosoftVolumeEncryption" -Class "Win32_EncryptableVolume" -Filter "DriveLetter = '$DriveLetter'"
    if(-not $BitLocker)
    {
        LogMessage("No BitLocker object")
        return $False
    }
    $protectionEnabled = $False
    switch ($BitLocker.GetProtectionStatus().protectionStatus){
        ("0"){
            LogMessage("Unprotected")
            break
        }
        ("1"){
            LogMessage("Protected")
            $protectionEnabled = $True
            break
        }
        ("2"){
            LogMessage("Uknown")
            break
        }
        default{
            LogMessage("NoReturn")
            break
        }
    }
    if (!$protectionEnabled)
    {
        LogMessage("Bitlocker isn’t enabled on the OS")
        return $False
    }
    $ProtectorIds = $BitLocker.GetKeyProtectors("0").volumekeyprotectorID
    $return = $False
    foreach ($ProtectorID in $ProtectorIds){
        $KeyProtectorType = $BitLocker.GetKeyProtectorType($ProtectorID).KeyProtectorType
        switch($KeyProtectorType){
            "1"{
                LogMessage("Trusted Platform Module (TPM)")
                $return = $True
                break
            }
            "4"{
                LogMessage("TPM And PIN")
                $return = $True
                break
            }
            "5"{
                LogMessage("TPM And Startup Key")
                $return = $True
                break
            }
            "6"{
                LogMessage("TPM And PIN And Startup Key")
                $return = $True
                break
            }
            default {break}
        }#endSwitch
    }#EndForeach
    if ($return)
    {
        LogMessage("Has TPM-based protector")
    }
    else
    {
        LogMessage("Doesn't have TPM-based protector")
    }
    return $return
}
function SetRegistrykeyForSuccess
{
    reg add HKLM\SOFTWARE\Microsoft\PushButtonReset /v WinREPathScriptSucceed_CVE_2024_20666 /d 1 /f
}
function TargetfileVersionExam([string]$mountDir)
{
    # Exam target binary
    $targetBinary=$mountDir + "\Windows\System32\winload.efi"
    LogMessage("TargetFile: " + $targetBinary)
    $realNTVersion = [Diagnostics.FileVersionInfo]::GetVersionInfo($targetBinary).ProductVersion
    $versionString = "$($realNTVersion.Split('.')[0]).$($realNTVersion.Split('.')[1])"
    $fileVersion = $($realNTVersion.Split('.')[2])
    $fileRevision = $($realNTVersion.Split('.')[3])
    LogMessage("Target file version: " + $realNTVersion)
    if (!($versionString -eq "10.0"))
    {
        LogMessage("Not Windows 10 or later")
        return $False
    }
    $hasUpdated = $False
    #Windows 10, version 1507 10240.20400
    #Windows 10, version 1607 14393.6610
    #Windows 10, version 1809 17763.5322
    #Windows 10, version 2004 1904X.3920
    #Windows 11, version 21H2 22000.2710
    #Windows 11, version 22H2 22621.3000
    switch ($fileVersion) {
        "10240" {
            LogMessage("Windows 10, version 1507")
            if ($fileRevision -ge 20400)
            {
                LogMessage("Windows 10, version 1507 with revision " + $fileRevision + " >= 20400, updates have been applied")
                $hasUpdated = $True
            }
            break
        }
        "14393" {
            LogMessage("Windows 10, version 1607")
            if ($fileRevision -ge 6610)
            {
                LogMessage("Windows 10, version 1607 with revision " + $fileRevision + " >= 6610, updates have been applied")
                $hasUpdated = $True
            }
            break
        }
        "17763" {
            LogMessage("Windows 10, version 1809")
            if ($fileRevision -ge 5322)
            {
                LogMessage("Windows 10, version 1809 with revision " + $fileRevision + " >= 5322, updates have been applied")
                $hasUpdated = $True
            }
            break
        }
        "19041" {
            LogMessage("Windows 10, version 2004")
            if ($fileRevision -ge 3920)
            {
                LogMessage("Windows 10, version 2004 with revision " + $fileRevision + " >= 3920, updates have been applied")
                $hasUpdated = $True
            }
            break
        }
        "22000" {
            LogMessage("Windows 11, version 21H2")
            if ($fileRevision -ge 2710)
            {
                LogMessage("Windows 11, version 21H2 with revision " + $fileRevision + " >= 2710, updates have been applied")
                $hasUpdated = $True
            }
            break
        }
        "22621" {
            LogMessage("Windows 11, version 22H2")
            if ($fileRevision -ge 3000)
            {
                LogMessage("Windows 11, version 22H2 with revision " + $fileRevision + " >= 3000, updates have been applied")
                $hasUpdated = $True
            }
            break
        }
        default {
            LogMessage("Warning: unsupported OS version")
        }
    }
    return $hasUpdated
}
function PatchPackage([string]$mountDir, [string]$packagePath)
{
    # Exam target binary
    $hasUpdated = TargetfileVersionExam($mountDir)
    if ($hasUpdated)
    {
        LogMessage("The update has already been added to WinRE")
        SetRegistrykeyForSuccess
        return $False
    }
    # Add package
    LogMessage("Apply package:" + $packagePath)
    Dism /Add-Package /Image:$mountDir /PackagePath:$packagePath
    if ($LASTEXITCODE -eq 0)
    {
        LogMessage("Successfully applied the package")
    }
    else
    {
        LogMessage("Applying the package failed with exit code: " + $LASTEXITCODE)
        return $False
    }
    # Cleanup recovery image
    LogMessage("Cleanup image")
    Dism /image:$mountDir /cleanup-image /StartComponentCleanup /ResetBase
    if ($LASTEXITCODE -eq 0)
    {
        LogMessage("Cleanup image succeed")
    }
    else
    {
        LogMessage("Cleanup image failed: " + $LASTEXITCODE)
        return $False
    }
    return $True
}
# ------------------------------------
# Execution starts
# ------------------------------------
# Check breadcrumb
if (Test-Path HKLM:\Software\Microsoft\PushButtonReset)
{
    $values = Get-ItemProperty -Path HKLM:\Software\Microsoft\PushButtonReset
    if (!(-not $values))
    {
        if (Get-Member -InputObject $values -Name WinREPathScriptSucceed_CVE_2024_20666)
        {
            $value = Get-ItemProperty -Path HKLM:\Software\Microsoft\PushButtonReset -Name WinREPathScriptSucceed_CVE_2024_20666
            if ($value.WinREPathScriptSucceed_CVE_2024_20666 -eq 1)
            {
                LogMessage("This script was previously run successfully")
                exit 1
            }
        }
    }
}
# Get WinRE info
$WinREInfo = Reagentc /info
$findLocation = $False
foreach ($line in $WinREInfo)
{
    $params = $line.Split(':')
    if ($params.count -le 1)
    {
        continue
    }
    if ($params[1].Lenght -eq 0)
    {
        continue
    }
    $content = $params[1].Trim()
    if ($content.Lenght -eq 0)
    {
        continue
    }
    $index = $content.IndexOf("\\?\")
    if ($index -ge 0)
    {
        LogMessage("Find \\?\ at " + $index + " for [" + $content + "]")
        $WinRELocation = $content
        $findLocation = $True
    }
}
if (!$findLocation)
{
    LogMessage("WinRE Disabled")
    exit 1
}
LogMessage("WinRE Enabled. WinRE location:" + $WinRELocation)
$WinREFile = $WinRELocation + "\winre.wim"
if ([string]::IsNullorEmpty($workDir))
{
    LogMessage("No input for mount directory")
    LogMessage("Use default path from temporary directory")
    $workDir = [System.IO.Path]::GetTempPath()
}
LogMessage("Working Dir: " + $workDir)
$name = "9f8131ee-878f-4525-bf31-e446aac3016a_Mount"
$mountDir = Join-Path $workDir $name
LogMessage("MountDir: " + $mountdir)
# Delete existing mount directory
if (Test-Path $mountDir)
{
    LogMessage("Mount directory: " + $mountDir + " already exists")
    LogMessage("Try to unmount it")
    Dism /unmount-image /mountDir:$mountDir /discard
    if (!($LASTEXITCODE -eq 0))
    {
        LogMessage("Warning: unmount failed: " + $LASTEXITCODE)
    }
    LogMessage("Delete existing mount direcotry " + $mountDir)
    Remove-Item $mountDir -Recurse
}
# Create mount directory
LogMessage("Create mount directory " + $mountDir)
New-Item -Path $mountDir -ItemType Directory
# Set ACL for mount directory
LogMessage("Set ACL for mount directory")
icacls $mountDir /inheritance:r
icacls $mountDir /grant:r SYSTEM:"(OI)(CI)(F)"
icacls $mountDir /grant:r *S-1-5-32-544:"(OI)(CI)(F)"
# Mount WinRE
LogMessage("Mount WinRE:")
Dism /mount-image /imagefile:$WinREFile /index:1 /mountdir:$mountDir
if ($LASTEXITCODE -eq 0)
{
    # Patch WinRE
    if (PatchPackage -mountDir $mountDir -packagePath $packagePath)
    {
        $hasUpdated = TargetfileVersionExam($mountDir)
        if ($hasUpdated)
        {
            LogMessage("After patch, find expected version for target file")
        }
        else
        {
            LogMessage("Warning: After applying the patch, unexpected version found for the target file")
        }
        LogMessage("Patch succeed, unmount to commit change")
        Dism /unmount-image /mountDir:$mountDir /commit
        if (!($LASTEXITCODE -eq 0))
        {
            LogMessage("Unmount failed: " + $LASTEXITCODE)
            exit 1
        }
        else
        {
            if ($hasUpdated)
            {
                if (IsTPMBasedProtector)
                {
                    # Disable WinRE and re-enable it to let new WinRE be trusted by BitLocker
                    LogMessage("Disable WinRE")
                    reagentc /disable
                    LogMessage("Re-enable WinRE")
                    reagentc /enable
                    reagentc /info
                }
                # Leave a breadcrumb indicates the script has succeed
                SetRegistrykeyForSuccess
            }
        }
    }
    else
    {
        LogMessage("Patch failed or is not applicable, discard unmount")
        Dism /unmount-image /mountDir:$mountDir /discard
        if (!($LASTEXITCODE -eq 0))
        {
            LogMessage("Unmount failed: " + $LASTEXITCODE)
            exit 1
        }
    }
}
else
{
    LogMessage("Mount failed: " + $LASTEXITCODE)
}
# Cleanup Mount directory in the end
LogMessage("Delete mount direcotry")
Remove-Item $mountDir -Recurse
STEP
更新プログラム「KB5034232」をダウンロード

こちらの公式サイトよりダウンロードします。

なお、私の環境は、Windows バージョン は 「22H2」。また、パソコン本体のマシンは「 x64-based Systems 」です。
私の場合は「2024-01 Dynamic Update for Windows 10 Version 22H2 for x64-based Systems (KB5034232)」をダウンロードしました。

参考情報:x64-based Systems と ARM64-based Systems と x86-based Systems を判断する方法
STEP
⊞ Windowsキー + R 」で“ファイル名を指定して実行”を起動
STEP
ms-settings:about 」で設定画面、システムの詳細情報が開く
ms-settings:about
STEP
表示されたページの「 デバイスの仕様 」で“システムの種類”を確認

詳細情報のページが開き、項目「 デバイスの仕様 」の“システムの種類” で判断可能。

下記の内容で判断

  • 表示 “64 ビット オペレーティングシステム、x64 ベース プロセッサ”

    結果 「x64-based Systems
    64bitのシステム用。多くのデスクトップPCやラップトップ(ノートパソコン)が該当する。
    大半のパソコンは、この環境が該当すると思われる。
     
  • 表示64ビット オペレーティングシステム、ARMベース プロセッサ

    結果「ARM64-based Systems
    64bitのシステム用。モバイルデバイス(スマートフォン)や軽量のラックトップが該当する。
     
  • 表示32ビット オペレーティングシステム、x86ベース プロセッサ

    結果「x86-based Systems
    32bitのシステム用。最新のパソコンは、ほぼ全て64bitアーキテクチャで販売されているため、
    古いパソコンなどが該当する。
     

仮に間違った環境用の更新プログラムをインストールしようとしても、チェックではじかれて、
エラーになるので間違えを恐れる必要はありません。

下記は、私の環境の「 x64-based Systems 」で確認した画面です。

システムの種類 “64 ビット オペレーティング システム、x64 ベース プロセッサ” 「x64-based Systems」と判断
画像:この画面ではシステムの種類が “64 ビット オペレーティング システム、x64 ベース プロセッサ” であり「x64-based Systems」と判断
補足事項:更新プログラム「KB5034232」とは

ここでダウンロードするKB5034232は、冒頭のエラーとなったKB5034441の説明でも記載している通り、本来はKB5034441で自動的に導入される更新プログラムが「KB5034232」です。

エラーとなった KB5034441経由で導入ができないので、手動でKB5034232をダウンロード。

なお、後述していますがこのKB5034232のインストール方法は、PowerShellスクリプトを使ってインストールします。

STEP
PowerShellウィンドウを管理者として実行

ファイル名を指定して実行で「powershell」と入力。つづいて「 Ctrl + Shift + Enterキー 」でコマンドプロンプトを管理者権限で実行する。

STEP
ダウンロードしたPowerShellスクリプトの場所に移動

私の場合、ダウンロードした“PatchWinREScript_2004plus.ps1”を保存した場所「 C:\Users\”ユーザー名”\Downloads 」に移動。

PS C:\WINDOWS\system32> cd "C:\Users\"ユーザー名"\Downloads"
PS C:\Users\"ユーザー名"\Downloads>
STEP
PowerShellの実行権限を確認
Get-ExecutionPolicy
PS C:\Users\"ユーザー名"\Downloads> Get-ExecutionPolicy
RemoteSigned
PS C:\Users\"ユーザー名"\Downloads>

もし、ここでのポリシーが「RemoteSigned」「Unrestricted」「Bypass」いずれかの場合はローカルのPowerShellスクリプトに対する制約が少なく実行可能な状態です。

それ以外のポリシーの場合、一時的にポリシーを変更する必要があります。ポリシーの変更方法は、ネットで検索していただくか、こちらの記事を参考にしてください。

STEP
PowerShellスクリプトの実行
.\PatchWinREScript_2004plus.ps1
PS C:\Users\"ユーザー名"\Downloads> .\PatchWinREScript_2004plus.ps1

コマンド パイプライン位置 1 のコマンドレット PatchWinREScript_2004plus.ps1
次のパラメーターに値を指定してください:
(ヘルプを表示するには、「!?」と入力してください。)
packagePath: 
STEP
最初にダウンロードした「KB5034232」の保存場所を絶対パスで指定する
PS C:\Users\"ユーザー名"\Downloads> .\PatchWinREScript_2004plus.ps1

コマンド パイプライン位置 1 のコマンドレット PatchWinREScript_2004plus.ps1
次のパラメーターに値を指定してください:
(ヘルプを表示するには、「!?」と入力してください。)
packagePath: "C:\Users\"ユーザー名"\Downloads\windows10.0-kb5034232-x64_ff4651e9e031bad04f7fa645dc3dee1fe1435f38.cab"
STEP
実行した後にPowerShellスクリプトが完了したことを確認
01/30/2024 11:13:29 - No input for mount directory
01/30/2024 11:13:30 - Use default path from temporary directory
01/30/2024 11:13:30 - Working Dir: C:\Users\"ユーザー名"\AppData\Local\Temp\
01/30/2024 11:13:30 - MountDir: C:\Users\"ユーザー名"\AppData\Local\Temp\CA551926-299B-27A55276EC22_Mount
01/30/2024 11:13:30 - Create mount directory C:\Users\"ユーザー名"\AppData\Local\Temp\CA551926-299B-27A55276EC22_Mount


    ディレクトリ: C:\Users\"ユーザー名"\AppData\Local\Temp


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        2024/01/30     11:13                CA551926-299B-27A55276EC22_Mount
01/30/2024 11:13:30 - Set ACL for mount directory
処理ファイル: C:\Users\"ユーザー名"\AppData\Local\Temp\CA551926-299B-27A55276EC22_Mount
1 個のファイルが正常に処理されました。0 個のファイルを処理できませんでした
処理ファイル: C:\Users\"ユーザー名"\AppData\Local\Temp\CA551926-299B-27A55276EC22_Mount
1 個のファイルが正常に処理されました。0 個のファイルを処理できませんでした
処理ファイル: C:\Users\"ユーザー名"\AppData\Local\Temp\CA551926-299B-27A55276EC22_Mount
1 個のファイルが正常に処理されました。0 個のファイルを処理できませんでした
01/30/2024 11:13:31 - Mount WinRE:
REAGENTC.EXE: 操作は成功しました。

01/30/2024 11:14:15 - TargetFile: C:\Users\"ユーザー名"\AppData\Local\Temp\CA551926-299B-27A55276EC22_Mount\Windows\System32\bootmenuux.dll
01/30/2024 11:14:15 - Target file version: 10.0.19041.1
01/30/2024 11:14:15 - Windows 10, version 2004
01/30/2024 11:14:15 - Apply package:"C:\Users\"ユーザー名"\Downloads\windows10.0-kb5034232-x64_ff4651e9e031bad04f7fa645dc3dee1fe1435f38.cab"
01/30/2024 11:14:53 - Successfully applied the package
01/30/2024 11:14:53 - Cleanup image
01/30/2024 11:17:38 - Cleanup image succeed
01/30/2024 11:17:38 - TargetFile: C:\Users\"ユーザー名"\AppData\Local\Temp\CA551926-299B-27A55276EC22_Mount\Windows\System32\bootmenuux.dll
01/30/2024 11:17:38 - Target file version: 10.0.19041.2247
01/30/2024 11:17:38 - Windows 10, version 2004
01/30/2024 11:17:38 - Windows 10, version 2004 with revision 2247 >= 2247, updates have been applied
01/30/2024 11:17:38 - After patch, find expected version for target file
01/30/2024 11:17:38 - Patch succeed, unmount to commit change

展開イメージのサービスと管理ツール
バージョン: 10.0.19041.3636

イメージを保存しています
[==========================100.0%==========================]
イメージのマウントを解除しています
[==========================100.0%==========================]
操作は正常に完了しました。
01/30/2024 11:18:42 - Checking BitLocker status
01/30/2024 11:18:43 - Unprotected
01/30/2024 11:18:43 - Bitlocker isn窶冲 enabled on the OS
この操作を正しく終了しました。
01/30/2024 11:18:43 - Delete mount direcotry


PS C:\Users\"ユーザー名"\Downloads>
補足事項:文字化けしているメッセージ「”日時” – Bitlocker isn窶冲 enabled on the OS」について

上記の結果でもわかる通り、「 ~ Bitlocker isn窶冲 enabled ~ 」となっています。
この現象を調べてみた結果、公式サイトに掲載されているPowerShellのコードで全角文字[(全角アポストロフィー)]が使用されていることが原因でした。

    if (!$protectionEnabled)
    {
        LogMessage("Bitlocker isn’t enabled on the OS")
        return $False
    }

この文字化けが発生しても処理自体に影響はありません。ただコンソールに誤って表示されるのみのため、無視してください。

STEP
エラーとなっているWindows Update で「再試行」ボタンをクリック
Windows Update エラー画面で再試行ボタンをクリック
画像:Windows Update エラー画面で「再試行ボタン」をクリック
STEP
エラーとなっていたKB5034441が正常にインストールされたことを確認
補足情報:対応2-2で紹介されているPowerShellスクリプトの制約について

PowerShellスクリプトでパーティションを拡張する方法(Microsoft公式の手順その2)で紹介されているPowerShellスクリプトについてです。

ざっくりPowerShellのコードを調べると、下記のような制約がありました。

  • 再起動直後であること
     
  • OSパーティションの直後にWinRE回復パーティションがあること
    ※ 直後とは、ディスクの管理上ですぐ右側の事を指す。
     
  • WinRE回復パーティションの空き領域が250MBより小さい事
     
  • WinRE回復パーティションに割り当て可能な空き領域が250MB以上あること
    ※ WinRE回復パーティションに割り当て可能な空き領域とは、WinRE回復パーティションの直後にある未割り当て領域の事を指す。
     
  • バックアップ先のフォルダーが存在すること

このPowerShell対応するためには、このPowerShellスクリプト + パーティション管理ソフト が必要になるでしょう。
より難易度が高く難しい対応方法となってしまいます。

参考情報:制約が多く実行できなかったPowerShellスクリプト:Resize_script.ps1

2024年3月現在のコードをコピペ。

Param (
[Parameter(Mandatory=$false,HelpMessage="Skip confirmation")][bool]$SkipConfirmation=$false,
[Parameter(Mandatory=$true,HelpMessage="Path to backup old WinRE partition content to")][string]$BackupFolder
)
# ------------------------------------
# Helper functions
# ------------------------------------
# Log message
function LogMessage([string]$message)
{
	$message = "$message"
	Write-Host $message
}
# Extract numbers from string
function ExtractNumbers([string]$str)
{
	$cleanString = $str -replace "[^0-9]"
	return [long]$cleanString
}
# Display partition info using fsutil
# Return an array, the first value is total size and the second value is free space
function DisplayPartitionInfo([string[]]$partitionPath)
{
	$volume = Get-WmiObject -Class Win32_Volume | Where-Object { $partitionPath -contains $_.DeviceID }
	LogMessage("  Partition capacity: " +  $volume.Capacity)
	LogMessage("  Partition free space: " + $volume.FreeSpace)
	return $volume.Capacity, $volume.FreeSpace
} 
# Display WinRE status
function DisplayWinREStatus()
{
	# Get WinRE partition info
	$WinREInfo = Reagentc /info
	foreach ($line in $WinREInfo)
	{
		$params = $line.Split(':')
		if ($params.Count -lt 2)
		{
			continue
		}
		if (($params[1].Trim() -ieq "Enabled") -Or (($params[1].Trim() -ieq "Disabled")))
		{
			$Status = $params[1].Trim() -ieq "Enabled"
			LogMessage($line.Trim())
		}
		if ($params[1].Trim() -like "\\?\GLOBALROOT*")
		{
			$Location = $params[1].Trim()
			LogMessage($line.Trim())
		}
	}
	
	return $Status, $Location
}
# ------------------------------------
# Main execution
# ------------------------------------
# Clear the error
$Error.Clear()
# ------------------------------------
# Examining the system to collect required info 
# for the execution
# Need to check WinRE status, collect OS and WinRE
# partition info
# ------------------------------------
LogMessage("Start time: $([DateTime]::Now)")
LogMessage("Examining the system...")
$NeedShrink = $true
$NeedCreateNew = $false
$NeedBackup = $false
# Get WinRE partition info
$InitialWinREStatus = DisplayWinREStatus
$WinREStatus = $InitialWinREStatus[0]
$WinRELocation = $InitialWinREStatus[1]
if (!$WinREStatus)
{
	LogMessage("Error: WinRE Disabled")
	exit 1
}
# Get System directory and ReAgent xml file
$system32Path = [System.Environment]::SystemDirectory
LogMessage("System directory: " + $system32Path)
$ReAgentXmlPath = Join-Path -Path $system32Path -ChildPath "\Recovery\ReAgent.xml"
LogMessage("ReAgent xml: " + $ReAgentXmlPath)
if (!(Test-Path  $ReAgentXmlPath))
{
	LogMessage("Error: ReAgent.xml cannot be found")
	exit 1
}
# Get OS partition
LogMessage("")
LogMessage("Collecting OS and WinRE partition info...")
$OSDrive = $system32Path.Substring(0,1)
$OSPartition = Get-Partition -DriveLetter $OSDrive
# Get WinRE partition
$WinRELocationItems = $WinRELocation.Split('\\')
foreach ($item in $WinRELocationItems)
{
    if ($item -like "harddisk*")
	{
		$OSDiskIndex = ExtractNumbers($item)
	}
	if ($item -like "partition*")
	{
		$WinREPartitionIndex = ExtractNumbers($item)
	}
}
LogMessage("OS Disk: " + $OSDiskIndex)
LogMessage("OS Partition: " + $OSPartition.PartitionNumber)
LogMessage("WinRE Partition: " + $WinREPartitionIndex)
$WinREPartition = Get-Partition -DiskNumber $OSDiskIndex -PartitionNumber $WinREPartitionIndex
$diskInfo = Get-Disk -number $OSDiskIndex
$diskType = $diskInfo.PartitionStyle
LogMessage("Disk PartitionStyle: " + $diskType)
# Display WinRE partition size info
LogMessage("WinRE partition size info")
$WinREPartitionSizeInfo = DisplayPartitionInfo($WinREPartition.AccessPaths)
LogMessage("WinRE Partition Offset: " + $WinREPartition.Offset)
LogMessage("WinRE Partition Type: " + $WinREPartition.Type)
LogMessage("OS partition size: " + $OSPartition.Size)
LogMessage("OS partition Offset: " + $OSPartition.Offset)
$OSPartitionEnds = $OSPartition.Offset + $OSPartition.Size
LogMessage("OS partition ends at: " + $OSPartitionEnds)
LogMessage("WinRE partition starts at: " + $WinREPartition.Offset)
$WinREIsOnSystemPartition = $false
if ($diskType -ieq "MBR")
{
	if ($WinREPartition.IsActive)
	{
		LogMessage("WinRE is on System partition")
		$WinREIsOnSystemPartition = $true
	}
}
if ($diskType -ieq "GPT")
{
	if ($WinREPartition.Type -ieq "System")
	{
		LogMessage("WinRE is on System partition")
		$WinREIsOnSystemPartition = $true
	}
}
# Checking the BackupFolder parameter
if ($PSBoundParameters.ContainsKey('BackupFolder'))
{
	LogMessage("")
	LogMessage("Backup Directory: [" + $BackupFolder + "]")
	
	$Needbackup = $true
	
	if ($WinREIsOnSystemPartition)
	{
		$Needbackup = $false
		LogMessage("WinRE is on System partition which will be preserved. No need to backup content")
	}
	else
	{
		if (Test-path $BackupFolder)
		{
			$items = Get-ChildItem -Path $BackupFolder
			if ($items)
			{
				LogMessage("Error: Existing backup directory is not empty")
				exit 1
			}
		}
		else
		{
			LogMessage("Creating backup directory...")
			try 
			{
				$item = New-Item -Path $BackupFolder -ItemType Directory -ErrorAction Stop
				if ($item)
				{
					LogMessage("Backup directory created")
				}
				else
				{
					LogMessage("Error: Failed to create backup directory [" + $BackupFolder + "]")
					exit 1
				}
			} catch 
			{
				LogMessage("Error: An error occurred: $_")
				exit 1
			}
		}
	}
}
# ------------------------------------
# Verify whether we meet requirements of execution
# - WinRE cannot be on OS partition for the extension
# - WinRE partition must be the next partition after OS partition
# - If WinRE partition already have >=250MB free space, no need to do repartition
# - If there is enough unallocated space to grow the WinRE partition size, skip shrinking OS
# 
# However, if the WinRE partition is before the OS partition, there is no chance to extend it
# As a result, it's better to create a new WinRE partition after the OS partition
# ------------------------------------
# Perform a few checks
LogMessage("")
LogMessage("Verifying if the WinRE partition needs to be extended or not...")
if (!(($diskType -ieq "MBR") -Or ($diskType -ieq "GPT")))
{
	LogMessage("Error: Got an unexpected disk partition style: " +$diskType)
	exit 1
}
# WinRE partition must be after OS partition for the repartition
if ($WinREPartitionIndex -eq $OSPartition.PartitionNumber)
{
	LogMessage("WinRE and OS are on the same partition, should not perform extension")
	exit 0
}
$supportedSize = Get-PartitionSupportedSize -DriveLetter $OSDrive
# if there is enough free space, skip extension
if ($WinREPartitionSizeInfo[1] -ge 250MB)
{
	LogMessage("More than 250 MB of free space was detected in the WinRE partition, there is no need to extend the partition")
	exit 0
}
if ($WinREPartition.Offset -lt $OSPartitionEnds)
{
	LogMessage("WinRE partition is not after OS partition, cannot perform extension")
	LogMessage("Need to create a new WinRE partition after OS partition")
	$NeedCreateNew = $true
	$NeedShrink = $true
	
	# Calculate the size of repartition
	# Will create a new WinRE partition with current WinRE partition size + 250 MB
	# The OS partition size will be shrunk by the new WinRE partition size
	$targetWinREPartitionSize = $WinREPartitionSizeInfo[0] + 250MB
	$shrinkSize = [Math]::Ceiling($targetWinREPartitionSize / 1MB) * 1MB
	$targetOSPartitionSize = $OSPartition.Size - $shrinkSize
	if ($targetOSPartitionSize -lt $supportedSize.SizeMin)
	{
		LogMessage("Error: The target OS partition size after shrinking is smaller than the supported minimum size, cannot perform the repartition")
		exit 1
	}
}
else
{
	if ($WinREIsOnSystemPartition)
	{
		LogMessage("WinRE parititon is after the OS partition and it's also System partition")
		LogMessage("Error: Got unexpected disk layout, cannot proceed")
		exit 1
	}
	if (!($WinREPartitionIndex -eq ($OSPartition.PartitionNumber + 1)))
	{
		LogMessage("Error: WinRE partition is not right after the OS partition, cannot extend WinRE partition")
		exit 1
	}
	# Calculate the size of repartition
	# Will shrink OS partitition by 250 MB
	$shrinkSize = 250MB
	$targetOSPartitionSize = $OSPartition.Size - $shrinkSize
	$targetWinREPartitionSize = $WinREPartitionSizeInfo[0] + 250MB
	$UnallocatedSpace = $WinREPartition.Offset - $OSPartitionEnds;
	# If there is unallocated space, consider using it
	if ($UnallocatedSpace -ge 250MB)
	{
		$UnallocatedSpace = $WinREPartition.Offset - $OSPartitionEnds;
		LogMessage("Found unallocated space between OS and WinRE partition: " + $UnallocatedSpace)
		LogMessage("There is already enough space to extend WinRE partition without shrinking the OS partition")
		$NeedShrink = $false
		$targetOSPartitionSize = 0
	}
	else
	{
		$shrinkSize = [Math]::Ceiling((250MB - $UnallocatedSpace)/ 1MB) * 1MB
		if ($shrinkSize > 250MB)
		{
			$shrinkSize = 250MB
		}
		$targetOSPartitionSize = $OSPartition.Size - $shrinkSize
		if ($targetOSPartitionSize -lt $supportedSize.SizeMin)
		{
			LogMessage("Error: The target OS partition size after shrinking is smaller than the supported minimum size, cannot perform the repartition")
			exit 1
		}
	}
}
# ------------------------------------
# Report execution plan and ask for user confirmation to continue
# ------------------------------------
# Report the changes planned to be executed, waiting for user confirmation
LogMessage("")
LogMessage("Summary of proposed changes")
if ($NeedCreateNew)
{
	LogMessage("Note: WinRE partition is before OS partition, need to create a new WinRE partition after OS partition")
	LogMessage("Will shrink OS partition by " + $shrinkSize)
	LogMessage("  Current OS partition size: " + $OSPartition.Size)
	LogMessage("  Target OS partition size after shrinking: " + $targetOSPartitionSize)
	LogMessage("New WinRE partition will be created with size: ", $targetWinREPartitionSize)
	if ($WinREIsOnSystemPartition)
	{
		LogMessage("Existing WinRE partition is also system partition, it will be preserved")
	}
	else
	{
		LogMessage("Existing WinRE partition will be deleted")
		LogMessage("  WinRE partition: Disk [" + $OSDiskIndex + "] Partition [" + $WinREPartitionIndex + "]")
		LogMessage("  Current WinRE partition size: " + $WinREPartitionSizeInfo[0])
	}
}
else
{
	if ($NeedShrink)
	{
		LogMessage("Will shrink OS partition by " + $shrinkSize)
		LogMessage("  Current OS partition size: " + $OSPartition.Size)
		LogMessage("  Target OS partition size after shrinking: " + $targetOSPartitionSize)
		if ($UnallocatedSpace -ge 0)
		{
			LogMessage("Unallocated space between OS and WinRE partition that will be used towards the new WinRE partition: " + $UnallocatedSpace)
		}
	}
	else
	{
		LogMessage("Will use 250MB from unallocated space between OS and WinRE partition")
	}
	LogMessage("Will extend WinRE partition size by 250MB")
	LogMessage("  WinRE partition: Disk [" + $OSDiskIndex + "] Partition [" + $WinREPartitionIndex + "]")
	LogMessage("  Current WinRE partition size: " + $WinREPartitionSizeInfo[0])
	LogMessage("  New WinRE partition size:     " + $targetWinREPartitionSize)
	LogMessage("WinRE will be temporarily disabled before extending the WinRE partition and enabled automatically in the end")
	if ($UnallocatedSpace -ge 100MB)
	{
		LogMessage("Warning: More than 100MB of unallocated space was detected between the OS and WinRE partitions")
		LogMessage("Would you like to proceed by using the unallocated space between the OS and the WinRE partitions?")
	}
}
if ($Needbackup)
{
	LogMessage("")
	LogMessage("The contents of the old WinRE partition will be backed up to [" + $BackupFolder + "]")
}
LogMessage("")
LogMessage("Please reboot the device before running this script to ensure any pending partition actions are finalized")
LogMessage("")
if ($SkipConfirmation)
{
	LogMessage("User chose to skip confirmation")
	LogMessage("Proceeding with changes...")
}
else
{
	$userInput = Read-Host -Prompt "Would you like to proceed? Y for Yes and N for No"
		
	if ($userInput -ieq "Y")
	{
		LogMessage("Proceeding with changes...")
	}
	elseif ($userInput -ieq "N")
	{
		LogMessage("Canceling based on user request, no changes were made to the system")
		exit 0
	}
	else
	{
		LogMessage("Error: Unexpected user input: [" + $userInput + "]") 
		exit 0
	}
}
LogMessage("")
LogMessage("Note: To prevent unexpected results, please do not interrupt the execution or restart your system")
# ------------------------------------
# Do the actual execution
# The main flow is:
# 1. Check whether ReAgent.xml has stage location and clear it for repartiion
# 2. Disable WinRE as WinRE partition will be deleted
# 3. Perform the repartition to create a larger WinRE partition
# 4. Re-enable WinRE
# ------------------------------------
LogMessage("")
# Load ReAgent.xml to clear Stage location
LogMessage("Loading [" + $ReAgentXmlPath + "] ...")
$xml = [xml](Get-Content -Path $ReAgentXmlPath)
$node = $xml.WindowsRE.ImageLocation
if (($node.path -eq "") -And ($node.guid -eq "{00000000-0000-0000-0000-000000000000}") -And ($node.offset -eq "0") -And ($node.id -eq "0"))
{
	LogMessage("Stage location info is empty")
}
else
{
	LogMessage("Clearing stage location info...")
	$node.path = ""
	$node.offset = "0"
	$node.guid= "{00000000-0000-0000-0000-000000000000}"
	$node.id="0"
	# Save the change
	LogMessage("Saving changes to [" + $ReAgentXmlPath + "]...")
	$xml.Save($ReAgentXmlPath)
}
# Disable WinRE
LogMessage("Disabling WinRE...")
reagentc /disable
if (!($LASTEXITCODE -eq 0))
{
	LogMessage("Warning: encountered an error when disabling WinRE: " + $LASTEXITCODE)
	exit $LASTEXITCODE
}
# Verify WinRE is under C:\Windows\System32\Recovery\WinRE.wim
$disableWinREPath = Join-Path -Path $system32Path -ChildPath "\Recovery\WinRE.wim"
LogMessage("Verifying that WinRE wim exists in downlevel at default location")
if (!(Test-Path $disableWinREPath))
{
	LogMessage("Error: Cannot find " + $disableWinREPath)
	
	# Re-enable WinRE
	LogMessage("Re-enabling WinRE on error...")
	reagentc /enable
	if (!($LASTEXITCODE -eq 0))
	{
		LogMessage("Warning: encountered an error when enabling WinRE: " + $LASTEXITCODE)
	}
	exit 1
}
# ------------------------------------
# Perform the repartition
# 1. Resize the OS partition
# 2. Delete the WinRE partition
# 3. Create a new WinRE partition
# ------------------------------------
LogMessage("Performing repartition to extend the WinRE partition ...")
# 1. Resize the OS partition
if ($NeedShrink)
{
	LogMessage("Shrinking the OS partition to create a larger WinRE partition")
	LogMessage("Resizing the OS partition to: [" + $targetOSPartitionSize + "]...")
	Resize-Partition -DriveLetter $OSDrive -Size $targetOSPartitionSize
	if ($Error.Count -gt 0) {
		LogMessage("Error: Resize-Partition encountered errors: " + $Error[0].Exception.Message)
		
		# Re-enable WinRE
		LogMessage("Re-enabling WinRE on error...")
		reagentc /enable
		if (!($LASTEXITCODE -eq 0))
		{
			LogMessage("Warning: encountered an error when enabling WinRE: " + $LASTEXITCODE)
		}
		exit 1
	}
	$OSPartitionAfterShrink = Get-Partition -DriveLetter $OSDrive
	LogMessage("Target partition size: " + $targetOSPartitionSize)
	LogMessage("Size of OS partition after shrinking: " + $OSPartitionAfterShrink.Size)
}
# 2. Delete the WinRE partition
LogMessage("")
if ($WinREIsOnSystemPartition)
{
	LogMessage("Existing WinRE partition is System partition, skipping deletion")
}
else
{	
	# If requested by user, backup rest of the content on WinRE partition to backup directory
	if ($Needbackup)
	{
		$sourcePath = $WinREPartition.AccessPaths[0] 
		LogMessage("Copying content on WinRE partition from [" + $sourcePath + "] to [" + $BackupFolder + "]...")
		
		# Copy-Item may have access issue with certain system folders, enumerate the children items and exlcude them
		$items = Get-ChildItem -LiteralPath $sourcePath -Force
		foreach ($item in $items)
		{
			if ($item.Name -ieq "System Volume Information")
			{
				continue
			}
			$sourceItemPath = Join-Path -Path $sourcePath -ChildPath $item.Name
			$destItemPath = Join-Path -Path $BackupFolder -ChildPath $item.Name
			try 
			{
				LogMessage("Copying [" + $sourceItemPath + "] to [" + $destItemPath + "]...")
				Copy-Item -LiteralPath $sourceItemPath -Destination $destItemPath -Recurse -Force
			} catch 
			{
				LogMessage("Error: An error occurred during copy: $_")
				exit 1
			}
		}
		
		LogMessage("Backup completed")
		LogMessage("")
	}
	LogMessage("Deleting WinRE partition: Disk [" + $OSDiskIndex + "] Partition [" + $WinREPartitionIndex + "]...")
	Remove-Partition -DiskNumber $OSDiskIndex -PartitionNumber $WinREPartitionIndex -Confirm:$false
	if ($Error.Count -gt 0) {
		LogMessage("Error: Remove-Partition encountered errors: " + $Error[0].Exception.Message)
		exit 1
	}
}
# A short sleep for the partition change
Sleep 5
# 3. Create a new WinRE partition
LogMessage("")
LogMessage("Creating new WinRE partition...")
LogMessage("Target size: " + $targetWinREPartitionSize)
if ($diskType -ieq "GPT")
{
	$partition = New-Partition -DiskNumber $OSDiskIndex -Size $targetWinREPartitionSize -GptType "{de94bba4-06d1-4d40-a16a-bfd50179d6ac}"
	
	$newPartitionIndex = $partition.PartitionNumber
	# A short sleep to make sure the partition is ready for formatting
	Sleep 2
	LogMessage("Formating the partition...")
	$result = Format-Volume -Partition $partition -FileSystem NTFS -Confirm:$false
	if ($Error.Count -gt 0) {
		LogMessage("Error: Format-Volume encountered errors: " + $Error[0].Exception.Message)
		exit 1
	}
}
else
{
	#$partition = New-Partition -DiskNumber $OSDiskIndex -Size $targetWinREPartitionSize -MbrType 0x27
	$targetWinREPartitionSizeInMb = [int]($targetWinREPartitionSize/1MB)
	$diskpartScript = 
@"
select disk $OSDiskIndex
create partition primary size=$targetWinREPartitionSizeInMb id=27
format quick fs=ntfs label="Recovery"
set id=27
"@
	$TempPath = $env:Temp
	$diskpartSciptFile = Join-Path -Path $TempPath -ChildPath "\ExtendWinRE_MBR_PowershellScript.txt"
	
	LogMessage("Creating temporary diskpart script to create Recovery partition on MBR disk...")
	LogMessage("Temporary diskpart script file: " + $diskpartSciptFile)
	$diskpartScript | Out-File -FilePath $diskpartSciptFile -Encoding ascii
	
	LogMessage("Executing diskpart script...")
	try 
	{
		$diskpartOutput = diskpart /s $diskpartSciptFile
		
		if ($diskpartOutput -match "DiskPart successfully") 
		{
			LogMessage("Diskpart script executed successfully")
		}
		else
		{
			LogMessage("Error executing diskpart script:" + $diskpartOutput)
			exit 1
		}
		LogMessage("Deleting temporary diskpart script file...")
		Remove-Item $diskpartSciptFile
	}
	catch 
	{
		LogMessage("Error executing diskpart script: $_")
		exit 1
	}
	
	$vol = Get-Volume -FileSystemLabel "Recovery"
	$newPartitionIndex = (Get-Partition | Where-Object { $_.AccessPaths -contains $vol.Path } ).PartitionNumber
}
if ($Error.Count -gt 0) 
{
	LogMessage("Error: New-Partition encountered errors: " + $Error[0].Exception.Message)
	exit 1
}
LogMessage("New Partition index: " + $newPartitionIndex)
# Re-enable WinRE
LogMessage("Re-enabling WinRE...")
reagentc /enable
if (!($LASTEXITCODE -eq 0))
{
	LogMessage("Warning: encountered an error when enabling WinRE: " + $LASTEXITCODE)
	exit $LASTEXITCODE
}
# In the end, Display WinRE status to verify WinRE is enabled correctly
LogMessage("")
LogMessage("WinRE Information:")
$FinalWinREStatus = DisplayWinREStatus
$WinREStatus = $FinalWinREStatus[0]
$WinRELocation = $FinalWinREStatus[1]
if (!$WinREStatus)
{
	LogMessage("Warning: WinRE Disabled")
}
$WinRELocationItems = $WinRELocation.Split('\\')
foreach ($item in $WinRELocationItems)
{
	if ($item -like "partition*")
	{
		$WinREPartitionIndex = ExtractNumbers($item)
	}
}
LogMessage("WinRE Partition Index: " + $WinREPartitionIndex)
$WinREPartition = Get-Partition -DiskNumber $OSDiskIndex -PartitionNumber $WinREPartitionIndex
$WinREPartitionSizeInfoAfter = DisplayPartitionInfo($WinREPartition.AccessPaths)
LogMessage("")
LogMessage("OS Information:")
$OSPartition = Get-Partition -DriveLetter $OSDrive
LogMessage("OS partition size: " + $OSPartition.Size)
LogMessage("OS partition Offset: " + $OSPartition.Offset)
if (!($WinREPartitionIndex -eq $newPartitionIndex))
{
	LogMessage("Warning: WinRE is installed to partition [" + $WinREPartitionIndex +"], but the newly created Recovery partition is [" + $newPartitionIndex + "]")
}
LogMessage("End time: $([DateTime]::Now)")
if ($NeedBackup)
{
	LogMessage("")
	LogMessage("The contents of the old WinRE partition has been backed up to [" + $BackupFolder + "]")
}
LogMessage("")
LogMessage("Successfully completed the operation")

対応3.Windows 11 に アップグレードする方法

この方法は、公式には紹介されていない方法であり、すべての環境で解消されるかは不明です。

OSのアップグレードはリスクの大きい作業となります。必要に応じてバックアップの取得なども検討してください。

また、意外と見落としがちな観点ですが、作業者が誤ってパソコンの電源を落としてしまう他に、
落雷による突発的な停電」や「家電を使いすぎてブレーカーが落ちる」なども注意が必要です。

しらたま

ヒント:開閉できるエリア

下記のようなエリアはクリックすると開閉可能っピ 👍

対応3.Windows 11 に アップグレードする方法
STEP
エラーが発生したKB5034441以外の更新プログラムがインストールされていること

Windows OS のアップグレードは、作業時点で配信されている更新プログラムをすべてインストールしたほうが安全です。

今回、エラーとなったKB5034441以外の更新プログラムはインストールしましょう。

Windows Update で KB5034441以外の更新プログラムを更新
画像:Windows Update で KB5034441以外の更新プログラムを更新
STEP
“ディスクの管理”で事前のパーティション構成を確認

回復パーティションの空き領域は「529 MB」の環境です。
理由はわかりませんが、250 MB 以上なのに今回のエラーが発生しました。

“ディスクの管理”で事前のパーティション構成を確認
画像:“ディスクの管理”で事前のパーティション構成を確認
STEP
Windows Update より Windows 11 の 「ダウンロードしてインストール」ボタンをクリック

Windows 11 のシステム要件を満たしている場合は、Windows Update 上に “Windows 11 の準備ができました。” というメッセージが表示されます。

そのメッセージに「ダウンロードしてインストール」ボタンがあります。

画像:Win11のシステム要件が満たされている環境の場合
画像:Win11のシステム要件が満たされている環境の場合
補足情報:システム要件を満たしているのに上記の画面が表示されない場合

もしかすると、以前に「今は Windows 10 の使用を継続します」をクリックした事により、
上記のようなWindows 11 アップグレードのメッセージが非表示状態になっているのかもしれません。

Windows Update 画面の右側メニューにある「インストールの準備が完了したかどうかを確認する」をクリックすると メッセージが再表示されるようになります。

なお、Windows Update 画面の右側メニューがそもそも表示されていないという方は、Windows Update 画面の横サイズを大きくする事で右側のメニューが表示されると思います。

Windows Update 画面でアップグレードメッセージが表示されていない場合
画像:Windows Update 画面でアップグレードメッセージが表示されていない場合
STEP
ソフトウェア ライセンス条項を確認し、「同意しインストール」をクリック

Windows 11 のOSデータがダウンロード後、ソフトウェア ライセンス条項が表示。

このボタンを押すとWindows Update 画面上でインストール処理が開始されます。

このインストール処理が完了後、自動でWindows OSが再起動されてしまうので、
ドキュメントを開いている場合は保存してから進めてください

Windows 11 アップグレード ソフトウェア ライセンス条項
画像:Windows 11 アップグレード ソフトウェア ライセンス条項
STEP
(インストールが完了し自動で再起動するまで待ち)

Windows 11 OS をインストール(アップグレード)中にも操作できますが、
極力、触らない方が良いです。

あと、操作しなくても画面は定期的にチェックする事をオススメします!

なぜ見る必要があるかというと、仮にエラーが発生してしまった場合の事を想定しているため。
どのような流れでエラーが発生したかという情報は、問題を切り分けるうえで重要な手がかりとなります。

ずっと画面に張り付いて見る必要はありませんが、定期的にチェックしましょう。

STEP
自動再起動後、問題なくWindows 11 OS が立ち上がった事を確認
アップグレードが正常終了し、Windows 11 OS が起動
画像:アップグレードが正常終了し、Windows 11 OS が起動
STEP
Windows Update 画面でエラーが発生していないか確認

エラーが発生していた更新プログラム「KB5034441」のエラーが表示されていない事を確認。
更新プログラム「KB5034441」は、Windows 10 向けの更新プログラムだったので、アップグレードによりエラーが解消しています。

Windows 11 の Windows Update でエラーが発生していない事を確認
画像:Windows 11 の Windows Update でエラーが発生していない事を確認
STEP
“ディスクの管理”で事後のパーティション構成を確認

上記の画面でもわかる通り、Windows 11 へのアップグレードにより「システムドライブのCドライブは縮小」し、「Windows 11 用の回復パーティションが新規作成」された状態になりました。
(自動で実行されているので、環境によって結果は変化。)

スクロールできます
総容量回復パーティション(Windows 10用)EFI システム パーティションシステムドライブ(Cドライブ)回復パーティション(Windows 11用)
事前931.50 GB529 MB99 MB930.88 GBなし
事後931.50 GB529 MB99 MB930.88 GB 930.08 GBなし 818 MB
表:Windows 11 アップグレード前後のパーティション構成
参考情報:Windows 11 にアップグレードできるシステム要件
  • プロセッサ(CPU)
    1 ギガヘルツ (GHz) 以上で 2 コア以上の64 ビット互換プロセッサまたは System on a Chip (SoC)。
     
  • メモリ
    4 ギガバイト (GB) 以上
     
  • ストレージ(HDD・SSD)
    64 GB 以上の記憶装置
     
  • システム ファームウェア
    UEFI、セキュア ブート対応
     
  • TPM
    トラステッド プラットフォーム モジュール (TPM) バージョン 2.0
     
  • グラフィックス カード
    DirectX 12 以上 (WDDM 2.0 ドライバー) に対応
     
  • ディスプレイ
    対角サイズ 9 インチ以上で 8 ビット カラーの高解像度 (720p) ディスプレイ
     
  • インターネット接続と Microsoft アカウント
    個人向け Windows 11 Pro と Windows 11 Home は、初期設定時にインターネット接続と Microsoft アカウントが必要。
    Windows 11 Home の S モードを解除する場合もインターネット接続が必要。
    すべての Windows 11 エディションで、更新の実行、ダウンロード、一部の機能を使用するために、インターネットのアクセスが必要。
    一部の機能を利用するにはMicrosoft アカウント が必要。

まとめ

  • Windows 10 で 配信されている更新プログラム「KB5034441」は、
    • Windows 10 向けの更新プログラムであること
    • WinRE(回復パーティション)の脆弱性をつき、一部エディションで使用できるセキュリティ機能、BitLockerの保護がすり抜けられてしまう可能性がある問題の対策
       
  • KB5034441のエラー「0x80070643」は、
    • Windows OS がインストールされているディスクと同じ場所に自動作成されているWinRE回復パーティションの空き領域が250 MB 以上ない為、エラーが発生。
      (理由は不明だが一部、例外的な環境もあり。)
       
  • 2024年3月現在、エラーの対応方法はおおきくわけて3つある
    • 対応1.エラーが発生している更新プログラムを一時的に非表示にする方法
      BitLockerが使用できるエディション、かつBitLockerを有効にしている環境が対象となる問題。
      その為、BitLockerを使用していないのであれば、無理して対応する必要がない。
      Windows Update 画面でエラーが表示されるのが気になる方は、一時的に更新プログラム「KB5034441」を非表示できる。
       
    • 対応2.回復パーティションを拡張して更新プログラムを導入する方法
      対応2-1 と 対応2-3 で対応可能。
      対応2-2 で紹介されているPowerShellスクリプトは制約が多く使用不可。
      • 対応2-1.手動でパーティションの拡張を行う方法
      • 対応2-2.PowerShellスクリプトでパーティションを拡張する方法
      • 対応2-3.WinREを再構成する方法
         
    • 対応3.Windows 11 に アップグレードする方法

繰り返しにはなりますが、この更新プログラムは、Windowsの一部エディションで有効にできるBitLocker機能に関連した問題です。
そもそもBitLockerを使えないエディションだったり、BitLockerを有効にしていない環境だった場合、問題が発生しません。
私個人の見解としては無理して、いま対応する必要はないと思っています

今後、Microsoftより正式な対応方法が公開されると思います。気長に待ちましょう。

サポート募集中

この記事はお役に立てたでしょうか。現在、サポートを募集しています。
コーヒーを一杯 ☕ ご馳走いただけないでしょうか。

この記事が気に入ったら
フォローしてね!

この記事をシェアする

コメント

コメントする

コメントは日本語で入力してください。(スパム対策)

CAPTCHA

目次