Introduction

忘備録。

開発メモ その261 Windows 11 を古いマシンにインストールする にてインストールした Windows 11 マシンに対して、いつまでたっても 23H2 のアップデートが降ってこない。
CPU とかのハードウェア要件をバイパスした影響だということに気づき、アップデートする方法を探したのが事の発端。

とはいえ、いきなり物理マシンで使うのは怖いので、Hyper-V 環境を用意してそちらで検証。

win11upgrade

How to do?

実は、Windows 10 から 11 へのアップグレードに関して、Windows 11 をインストールする方法 というページで CPU 等の条件チェックを回避する方法を Microsoft が公式として説明している。

ページ自体は Windows 10 から 11 へのアップグレードだが、21H2 から 23H2 のようなアップデートにも対応できる。

ただし、

TPM 2.0 (少なくとも TPM 1.2 が必要) のチェック、CPU ファミリ、CPU モデルをバイパスできます。

とあるように、TPM 自体は 1.2 が最低でも必要で、このチェックだけは回避できない。

TPM 自体のチェックを回避する方法は後述。

1. 普通にアップデートを実行

まずは何も対処しないでアップデートを実施。

win11upgrade
Windows 11 の iso を挿入し、 setup.exe を実行。

win11upgrade

win11upgrade

win11upgrade

win11upgrade
ここで、条件チェックに引っかかる。

2. ハードウェア要件回避を実行

先の Micorsoft の公式手順に従い、レジストリを変更する。

1
2
$ reg add HKEY_LOCAL_MACHINE\SYSTEM\Setup\MoSetup /v AllowUpgradesWithUnsupportedTPMOrCPU /t REG_DWORD /d 1 /f
The operation completed successfully.

再度、setup.exe から再開する。

win11upgrade
が、TPM だけは回避できない。

これも公式手順通りで、当該のマシンには TPM 自体が組み込まれていないため、TPM 1.2 以上という条件を満たすことができず、チェックを回避できない。

3. TPM のチェックを回避

によれば、TPM のチェックどころか、ハードウェア要件のチェック全体を回避できるバッチスクリプトが存在するとのこと。
それが

である。

このバッチを管理者で実行し、再度 setup.exe を実行すればいい。

1
2
3
4
5
$ Skip_TPM_Check_on_Dynamic_Update.cmd

Skip TPM Check on Dynamic Update V13 INSTALLED run again to remove

Waiting for 0 seconds, press a key to continue ...

一応、このバッチ Skip_TPM_Check_on_Dynamic_Update.cmd の中身を張っておく。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
@(set '(=)||' <# lean and mean cmd / powershell hybrid #> @'

::# Get 11 on 'unsupported' PC via Windows Update or mounted ISO (no patching needed)
::# if WU is stuck use windows_update_refresh.bat; Beta/Dev/Canary needs OfflineInsiderEnroll
::# V13: skip 2nd tpm check on Canary iso; no Server label; future proofing; tested with 26010 iso, wu and wu repair version

@echo off & title get 11 on 'unsupported' PC || AveYo 2023.12.07
if /i "%~f0" neq "%SystemDrive%\Scripts\get11.cmd" goto setup
powershell -win 1 -nop -c ";"
set CLI=%*& set SOURCES=%SystemDrive%\$WINDOWS.~BT\Sources& set MEDIA=.& set MOD=CLI& set PRE=WUA& set /a VER=11
if not defined CLI (exit /b) else if not exist %SOURCES%\SetupHost.exe (exit /b)
if not exist %SOURCES%\WindowsUpdateBox.exe mklink /h %SOURCES%\WindowsUpdateBox.exe %SOURCES%\SetupHost.exe
reg add HKLM\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate /f /v DisableWUfBSafeguards /d 1 /t reg_dword
reg add HKLM\SYSTEM\Setup\MoSetup /f /v AllowUpgradesWithUnsupportedTPMorCPU /d 1 /t reg_dword
set OPT=/Compat IgnoreWarning /MigrateDrivers All /Telemetry Disable
set /a restart_application=0x800705BB & (call set CLI=%%CLI:%1 =%%)
set /a incorrect_parameter=0x80070057 & (set SRV=%CLI:/Product Client =%)
set /a launch_option_error=0xc190010a & (set SRV=%SRV:/Product Server =%)
for %%W in (%CLI%) do if /i %%W == /PreDownload (set MOD=SRV)
for %%W in (%CLI%) do if /i %%W == /InstallFile (set PRE=ISO& set "MEDIA=") else if not defined MEDIA set "MEDIA=%%~dpW"
if %VER% == 11 for %%W in ("%MEDIA%appraiserres.dll") do if exist %%W if %%~zW == 0 set AlreadyPatched=1 & set /a VER=10
if %VER% == 11 findstr /r "P.r.o.d.u.c.t.V.e.r.s.i.o.n...1.0.\..0.\..2.[2-9]" %SOURCES%\SetupHost.exe >nul 2>nul || set /a VER=10
if %VER% == 11 if not exist "%MEDIA%EI.cfg" (echo;[Channel]>%SOURCES%\EI.cfg & echo;_Default>>%SOURCES%\EI.cfg)
if %VER%_%PRE% == 11_ISO (%SOURCES%\WindowsUpdateBox.exe /Product Server /PreDownload /Quiet %OPT%)
if %VER%_%PRE% == 11_ISO (del /f /q %SOURCES%\appraiserres.dll 2>nul & cd.>%SOURCES%\appraiserres.dll & call :canary)
if %VER%_%MOD% == 11_SRV (set ARG=%OPT% %SRV% /Product Server)
if %VER%_%MOD% == 11_CLI (set ARG=%OPT% %CLI%)
%SOURCES%\WindowsUpdateBox.exe %ARG%
if %errorlevel% == %restart_application% (call :canary & %SOURCES%\WindowsUpdateBox.exe %ARG%)
exit /b

:canary iso skip 2nd tpm check by AveYo
set C= $X='%SOURCES%\hwreqchk.dll'; $Y='SQ_TpmVersion GTE 1'; $Z='SQ_TpmVersion GTE 0'; if (test-path $X) {
set C=%C% try { takeown.exe /f $X /a; icacls.exe $X /grant *S-1-5-32-544:f; attrib -R -S $X; [io.file]::OpenWrite($X).close() }
set C=%C% catch { return }; $R=[Text.Encoding]::UTF8.GetBytes($Z); $l=$R.Length; $i=2; $w=!1;
set C=%C% $B=[io.file]::ReadAllBytes($X); $H=[BitConverter]::ToString($B) -replace '-';
set C=%C% $S=[BitConverter]::ToString([Text.Encoding]::UTF8.GetBytes($Y)) -replace '-';
set C=%C% do { $i=$H.IndexOf($S, $i + 2); if ($i -gt 0) { $w=!0; for ($k=0; $k -lt $l; $k++) { $B[$k + $i / 2]=$R[$k] } } }
set C=%C% until ($i -lt 1); if ($w) { [io.file]::WriteAllBytes($X, $B); [GC]::Collect() } }
if %VER%_%PRE% == 11_ISO powershell -nop -c iex($env:C) >nul 2>nul
exit /b

:setup
::# elevate with native shell by AveYo
>nul reg add hkcu\software\classes\.Admin\shell\runas\command /f /ve /d "cmd /x /d /r set \"f0=%%2\"& call \"%%2\" %%3"& set _= %*
>nul fltmc|| if "%f0%" neq "%~f0" (cd.>"%temp%\runas.Admin" & start "%~n0" /high "%temp%\runas.Admin" "%~f0" "%_:"=""%" & exit /b)

::# lean xp+ color macros by AveYo: %<%:af " hello "%>>% & %<%:cf " w\"or\"ld "%>% for single \ / " use .%|%\ .%|%/ \"%|%\"
for /f "delims=:" %%s in ('echo;prompt $h$s$h:^|cmd /d') do set "|=%%s"&set ">>=\..\c nul&set /p s=%%s%%s%%s%%s%%s%%s%%s<nul&popd"
set "<=pushd "%appdata%"&2>nul findstr /c:\ /a" &set ">=%>>%&echo;" &set "|=%|:~0,1%" &set /p s=\<nul>"%appdata%\c"

::# toggle when launched without arguments, else jump to arguments: "install" or "remove"
set CLI=%*& (set IFEO=HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options)
wmic /namespace:"\\root\subscription" path __EventFilter where Name="Skip TPM Check on Dynamic Update" delete >nul 2>nul & rem v1
reg delete "%IFEO%\vdsldr.exe" /f 2>nul & rem v2 - v5
if /i "%CLI%"=="" reg query "%IFEO%\SetupHost.exe\0" /v Debugger >nul 2>nul && goto remove || goto install
if /i "%~1"=="install" (goto install) else if /i "%~1"=="remove" goto remove

:install
mkdir %SystemDrive%\Scripts >nul 2>nul & copy /y "%~f0" "%SystemDrive%\Scripts\get11.cmd" >nul 2>nul
reg add "%IFEO%\SetupHost.exe" /f /v UseFilter /d 1 /t reg_dword >nul
reg add "%IFEO%\SetupHost.exe\0" /f /v FilterFullPath /d "%SystemDrive%\$WINDOWS.~BT\Sources\SetupHost.exe" >nul
reg add "%IFEO%\SetupHost.exe\0" /f /v Debugger /d "%SystemDrive%\Scripts\get11.cmd" >nul
echo;
%<%:f0 " Skip TPM Check on Dynamic Update V13 "%>>% & %<%:2f " INSTALLED "%>>% & %<%:f0 " run again to remove "%>%
if /i "%CLI%"=="" timeout /t 7
exit /b

:remove
del /f /q "%SystemDrive%\Scripts\get11.cmd" "%Public%\get11.cmd" "%ProgramData%\get11.cmd" >nul 2>nul
reg delete "%IFEO%\SetupHost.exe" /f >nul 2>nul
echo;
%<%:f0 " Skip TPM Check on Dynamic Update V13 "%>>% & %<%:df " REMOVED "%>>% & %<%:f0 " run again to install "%>%
if /i "%CLI%"=="" timeout /t 7
exit /b

'@); $0 = "$env:temp\Skip_TPM_Check_on_Dynamic_Update.cmd"; ${(=)||} -split "\r?\n" | out-file $0 -encoding default -force; & $0
# press enter

インストール再開後、ハードウェア要件のチェックを回避し、次の画面に進むことができるはず。

win11upgrade

win11upgrade

win11upgrade

win11upgrade

win11upgrade

win11upgrade

長い更新を終えて無事に 23H2 に