Перевести парк Windows 11 на новую версию можно двумя путями: полным обновлением функциональности на несколько гигабайт или маленьким пакет включения Windows 11 — файлом на сотню-другую килобайт, который лишь «включает» уже лежащие в системе компоненты. Набор Windows-11-25H2-Update-Script автоматизирует второй путь: два скрипта PowerShell и их сокращённые варианты для cmd.exe, гейты версии и выпуска, проверка пакета по SHA-1 и подписи Microsoft, журнал прогона и — в версии 1.1.0 — настоящий read-only режим -WhatIf и 57 тестов Pester. Ниже — что именно проверяется до скачивания, чем поведение отличается от того, что обещает README, и какие места в документации уже разошлись с кодом.

TL;DR: что это и как проверить за десять минут
- Задача. Перевести хост Windows 11 на 25H2 или 26H2 без скачивания образа и без переустановки.
- Форма.
Upgrade-Win11-To-26H2.ps1(полная реализация) и.bat(сокращённый вариант), плюс такая же пара для 25H2 из версии 1.0.0. - Гейты. 24H2 сборка 26100.9546+ или 25H2 сборка 26200.9550+; домашние и корпоративные выпуски, но не LTSC и не Windows Server; 26H1 (28000+) отклоняется.
- Проверка пакета. Закреплённый адрес CDN Microsoft, SHA-1 из имени файла, подпись Authenticode, порог 100 000 байт.
- Главное. Код
0означает «пакет принят и подготовлен», а не «сборка изменилась»: проверятьCurrentBuild = 26300нужно после перезагрузки.
# read-only предполёт: печатает сборку, выпуск, архитектуру, пакет и цель, ничего не пишет
.\Upgrade-Win11-To-26H2.ps1 -WhatIf
# установка с отложенной перезагрузкой: применяется в окне обслуживания вручную
.\Upgrade-Win11-To-26H2.ps1 -Reboot None
Проблема, которую это решает
Функциональное обновление Windows привычно означает скачивание образа на несколько гигабайт и полчаса ожидания. Для 24H2 → 25H2 → 26H2 это не так: все три версии используют одно ядро, и переход выполняется пакетом включения — небольшим MSU, который активирует уже присутствующие компоненты и требует одной перезагрузки. По данным README разница выглядит так: традиционное обновление — 3–5 ГБ и 30+ минут, пакет включения — около 50 КБ и 1–2 минуты.
Экономия времени — не главное. Главное, что такой переход управляем: его можно поставить на паузу, отложить перезагрузку в окно обслуживания, проверить до установки и получить журнал. Именно этого не хватает ручному «нажмите в Параметрах обновление», особенно когда хостов десятки.
Тут же возникают три практические проблемы. Первая — пакет надо откуда-то взять, а в каталоге обновлений Microsoft его нет: URL отдаются только через службу доставки, и они «живут» не вечно. Вторая — нельзя поставить пакет на хост, который к нему не готов: другая сборка, другой выпуск, ветка 26H1 — всё это надо отсеять до скачивания, а не после. Третья — код возврата врёт: успешная установка пакета не означает, что версия изменилась, потому что сборка меняется на перезагрузке.
Набор решает именно эти три задачи и почти ничего больше: он не ищет обновления, не работает с Windows Update, не откатывает изменения.
Что такое пакет включения и чем он отличается от обновления функций
Пакет включения (enablement package, eKB) — это MSU-файл, который не содержит новых двоичных файлов, а переключает режим уже установленной системы. Отсюда его размер и время установки.
| Что сравнивается | Обновление функций (feature update) | Пакет включения |
|---|---|---|
| Объём загрузки | гигабайты | сотни килобайт (KB5054156 ~50 КБ, KB5121794 ~174 КБ) |
| Время установки | десятки минут | минуты |
| Перезагрузок | несколько | одна |
| Что происходит | замена компонентов системы | активация уже лежащих компонентов |
| Откат | штатный механизм отката обновления | вне области этих скриптов |
Именно из-за «переключения» пакет так чувствителен к исходной сборке: если на хосте не установлены предварительные накопительные обновления, включать нечего. В наборе это выражено гейтом версии — минимальная сборка 26100.9546 для 24H2 и 26200.9550 для 25H2, что соответствует KB5124010 или более позднему накопительному обновлению.
Возможности: два пути обновления
Набор — это фактически два независимых инструмента под одной крышей, и первый вопрос при выборе: какой путь нужен.
| Путь | Файлы | Пакет | Целевая сборка | Что нужно |
|---|---|---|---|---|
| 25H2 (версия 1.0.0) | Upgrade-Win11-To-25H2.ps1, .bat |
KB5054156 | 26200.6718 | 24H2 сборка 26100.5074+ |
| 26H2 (версия 1.1.0) | Upgrade-Win11-To-26H2.ps1, .bat |
KB5121794 | 26300.x | 24H2 26100.9546+ или 25H2 26200.9550+ |
Скрипты 25H2 в версии 1.1.0 не менялись — это сказано и в заметках к релизу, и в README. Практический вывод: если хост уже на 25H2, обновлять надо второй парой, а первая останется нетронутой.
Гейты: что отсекается до скачивания
| Гейт | Правило | Что происходит при несовпадении |
|---|---|---|
| Версия | 26100.9546+ на 24H2, 26200.9550+ на 25H2 | отказ: хост не готов к пакету |
| Выпуск | Home, Pro, Enterprise, Education, Enterprise multi-session, IoT Enterprise | LTSC и Windows Server отклоняются |
| Архитектура | AMD64 или ARM64, ARM проверяется первым | неизвестная архитектура — отказ либо требование -Architecture |
| Целевая ветка | любая 26300.x — это 26H2; 28000+ (26H1) — отдельная ветка | 26H1 отклоняется до любых действий |
| Пакет | закреплённый адрес CDN, SHA-1 из имени файла, подпись, порог 100 000 байт | отказ без установки |
Порядок важен: администратор проверяется первым, а предполётный режим — раньше создания журнала. В коде это видно буквально: комментарий рядом с проверкой прав говорит, что гейт прав выполняется до любой записи, а блок создания каталога журнала обёрнут условием «если это не preflight».
Проверка пакета
| Что проверяется | Как | Почему так |
|---|---|---|
| Целостность | SHA-1, взятый из имени файла пакета | отпечаток опубликован в самом имени, сверять не с чем-то внешним |
| Подлинность | Get-AuthenticodeSignature, подписант Microsoft |
подпись подтверждает, что файл выпущен Microsoft |
| Правдоподобность размера | порог 100 000 байт | отсекает обрезанную загрузку и HTML-страницу ошибки вместо файла |
Для локальной копии, переданной через -PackagePath, проверка SHA-1 пропускается: отпечаток принадлежит копии из каталога, а локальный файл может быть пересобран. Подпись Authenticode при этом всё равно проверяется — это разумный компромисс, и он описан в документации.
Как это устроено внутри
Скрипт — это линейный конвейер с явными выходами: любой отказ завершает работу до изменения системы, а не «пробует дальше».
flowchart TB
subgraph P25["путь 25H2, версия 1.0.0"]
A1["Upgrade-Win11-To-25H2.ps1: полная реализация"]
A2["Upgrade-Win11-To-25H2.bat: сокращённый вариант cmd.exe"]
end
subgraph P26["путь 26H2, версия 1.1.0"]
B1["Upgrade-Win11-To-26H2.ps1: гейты, WhatIf, SHA-1 и Authenticode"]
B2["Upgrade-Win11-To-26H2.bat: /whatif, certutil SHA-1"]
B3["tests: 57 тестов Pester на фикстурах"]
end
MS["catalog.sf.dl.delivery.mp.microsoft.com: KB5054156 и KB5121794"]
LOG["%ProgramData%\Win11-26H2\Upgrade_*.log: журнал прогона"]
OS["wusa.exe: установка пакета и переход сборки"]
B1 --> MS
B1 --> LOG
B1 --> OS
B2 --> MS
B2 --> OS
A1 --> MS
A1 --> OSПорядок шагов в коде 26H2 выглядит так: проверка прав, предполёт при -WhatIf, гейты, скачивание, проверка пакета, установка через wusa.exe, обработка кода возврата, политика перезагрузки. Журнал создаётся только в боевом режиме — при -WhatIf ни каталога, ни файла журнала не появляется.
flowchart TD
START["запуск в elevated-сессии"] --> ADMIN{"есть права администратора?"}
ADMIN -- нет --> STOP1["код 1: Administrator privileges required"]
ADMIN -- да --> PRE{"WhatIf передан?"}
PRE -- да --> PREFLIGHT["preflight: печатает сборку, выпуск, архитектуру, пакет и цель, ничего не пишет"]
PRE -- нет --> GATE{"гейт версии и выпуска пройден?"}
GATE -- "сборка ниже, LTSC, Server, 26H1" --> STOP2["отказ без изменений в системе"]
GATE -- да --> DL["скачивание пакета: BITS, затем HTTP, до RetryCount попыток"]
DL --> VER{"SHA-1 из имени файла и подпись Microsoft сходятся?"}
VER -- нет --> STOP3["код 1: Invalid signature status, установки нет"]
VER -- да --> INST["wusa.exe /quiet /norestart"]
INST --> CODE{"код возврата wusa"}
CODE -- "0 или 3010" --> RB{"политика -Reboot"}
RB -- "None" --> WAIT["ждём окно обслуживания: сборка меняется только после перезагрузки"]
RB -- "Prompt или Force" --> REBOOT["перезагрузка по правилу"]
CODE -- другой --> STOP4["код 1: разбор кода в журнале"]Отдельно про скачивание. Скрипт использует BITS, если служба существует, и падает на HTTP, если её нет. Здесь есть известный пробел, о котором говорит сам AGENTS.md: обратного перехода «BITS не сработал — пробуем HTTP в этой же попытке» нет. То есть при живом, но сломанном BITS все попытки уйдут в BITS.
Альтернатива на cmd.exe устроена проще: те же гейты версии и выпуска, curl.exe с откатом на pwsh/powershell внутри каждой из трёх попыток, проверка SHA-1 через certutil, /whatif для предполёта. Чего в ней нет: проверки подписи Authenticode, транскрипта и настраиваемого числа попыток.
Замеры и цифры
Числа ниже — из заметок к релизу 1.1.0, из кода на main и из моих собственных проверок на этой машине (скачивание артефактов и разбор параметров без выполнения скрипта).
| Что измерено | Значение | Откуда |
|---|---|---|
| Размер пакета KB5121794, x64 | 177 535 байт | заметки к релизу |
| Размер пакета KB5121794, ARM64 | 178 969 байт | заметки к релизу |
| Порог подозрительно малого файла | 100 000 байт | MinimumPackageBytes в коде |
| Минимальная сборка 24H2 | 26100.9546 | константы гейта |
| Минимальная сборка 25H2 | 26200.9550 | константы гейта |
| Целевая сборка | 26300 (первая GA — 26300.9457) | константы TargetBuild, FirstGaBuild |
| Отклоняемая ветка | 28000+ (26H1) | константа OtherBranchBuild |
| Тестов Pester | 57 | заметки к релизу, каталог tests\ |
| Артефактов в релизе | 3 (два скрипта и SHA256SUMS.txt) |
gh release list, gh release download |
| SHA-256 скрипта 26H2 | 349521e3…224fb, совпал с SHA256SUMS.txt |
мой замер Get-FileHash |
| SHA-256 bat-файла | 5911929e…bc35b, совпал с SHA256SUMS.txt |
мой замер Get-FileHash |
| Параметры скрипта 26H2 | Reboot, RetryCount, RetryDelaySec, Architecture, PackagePath | разбор AST без выполнения |
CmdletBinding в 26H2 / в 25H2 |
есть (с SupportsShouldProcess) / нет |
разбор AST без выполнения |

Две строки таблицы стоит прочитать внимательно. Первая: -WhatIf в скрипте 26H2 не объявлен как отдельный параметр — он приходит от [CmdletBinding(SupportsShouldProcess = $true)], а код читает $WhatIfPreference. Именно поэтому в списке параметров его нет, хотя режим работает. Вторая: у скрипта 25H2 CmdletBinding отсутствует вовсе, то есть -WhatIf там не появится ни при каких обстоятельствах, хотя README в примерах для 25H2 его упоминает.
Почему это круто
- Предполёт, который действительно ничего не пишет.
-WhatIfпечатает сборку, выпуск, архитектуру, пакет и цель — и не создаёт ни каталога, ни журнала, ни загрузки. - Гейты стоят до скачивания. Хост на неподходящей сборке или LTSC-выпуске отсекается до того, как потратит трафик и время.
- Проверка двойная. SHA-1 из имени файла ловит битую загрузку, Authenticode — подмену источника.
- Журнал на каждый прогон. Транскрипт в
%ProgramData%остаётся на хосте, и разбор инцидента идёт по нему, а не по памяти. - Честная формулировка про код 0. Документация прямо говорит: код 0 — «пакет подготовлен», а не «версия изменилась», и требует проверки сборки после перезагрузки.
- Тесты на фикстурах. 57 тестов Pester проверяют именно решения, а не систему: они форсируют ветку и утверждают отсутствие загрузки и установки, поэтому безопасны на любом хосте.
- Альтернатива для cmd.exe. Полноценного PowerShell на всех хостах не бывает, и сокращённый вариант с
certutilзакрывает эту дыру — с честно перечисленными потерями. - Ничего лишнего. Скрипт не трогает Windows Update, не ставит службы, не пишет телеметрию.
Установка
Устанавливать нечего: оба скрипта работают из клона репозитория. Это не фигура речи — в дереве нет ни установщика, ни VERSION, ни каталога документации.
git clone https://github.com/paulmann/Windows-11-25H2-Update-Script.git
cd Windows-11-25H2-Update-Script
Get-Help .\Upgrade-Win11-To-26H2.ps1 -Full # параметры читаются из фактического файла
Альтернатива — взять файлы из релиза и сверить их по опубликованным хешам:
gh release download v1.1.0 -R paulmann/Windows-11-25H2-Update-Script -D .\rel
Get-FileHash .\rel\Upgrade-Win11-To-26H2.ps1 -Algorithm SHA256
# сверить с первой строкой SHA256SUMS.txt
Два замечания по раскладке, которые экономят время. Первое: в дереве нет файла VERSION — версия видна только по бейджу README и разделу истории версий, поэтому единственный надёжный способ узнать, что перед вами, — прочитать Get-Help и заголовок скрипта. Второе: .gitattributes в репозитории помечает batch-файлы как CRLF, и это не косметика — goto и метки в .bat ломаются, если переводы строк привести к LF при checkout.
| Требование | Зачем | Как проверить |
|---|---|---|
| Административные права | проверка прав идёт первой | net session без ошибки или whoami /groups |
| Windows 11 24H2 сборка 26100.9546+ либо 25H2 26200.9550+ | ниже — отказ «Unsupported Windows version» | winver, ключ CurrentBuild и UBR |
| x64 или ARM64 | другая архитектура отклоняется | $env:PROCESSOR_ARCHITECTURE |
| Исходящий HTTPS к каталогу Microsoft | загрузка пакета | Test-NetConnection catalog.sf.dl.delivery.mp.microsoft.com -Port 443 |
| Политика выполнения скриптов | иначе скрипт завершится с кодом 1 | Get-ExecutionPolicy -List |
| Окно обслуживания и право на перезагрузку | установка меняет сборку ОС | вне области скриптов, решается организационно |
Настройка
Настраивать нечего в привычном смысле: нет ни файла конфигурации, ни параметров реестра, ни переменных окружения. Поведение задаётся только параметрами запуска.
flowchart LR PARAMS["параметры: -Reboot, -RetryCount, -RetryDelaySec, -Architecture, -PackagePath, -WhatIf"] --> BEH["поведение прогона"] BEH --> R1["-Reboot None: отложить перезагрузку"] BEH --> R2["-PackagePath: локальная копия пакета вместо сети"] BEH --> R3["-Architecture: обойти неопознанную архитектуру в preflight"] FILES["что создаётся на хосте"] --> F1["%ProgramData%\Win11-26H2\Upgrade_*.log"] FILES --> F2["%TEMP%\kb5121794_ARCH.msu, удаляется после прогона"] REC["что проверять после перезагрузки"] --> C1["CurrentBuild = 26300"] REC --> C2["DisplayVersion = 26H2"]
| Параметр | Значения | По умолчанию | Что меняет |
|---|---|---|---|
-Reboot |
Prompt, Force, None |
Prompt |
Force перезагружает сразу, Prompt спрашивает, None только предупреждает |
-RetryCount |
1–10 | 3 | число попыток загрузки |
-RetryDelaySec |
1–60 | 5 | пауза между попытками |
-Architecture |
AMD64, ARM64 |
автоопределение | нужен, когда архитектура не опознана, особенно в -WhatIf |
-PackagePath |
путь к локальному MSU | нет | установка из заранее проверенной копии |
-WhatIf |
переключатель | выключен | предполётный режим без записи |
Важная оговорка про -Reboot: обработчик перезагрузки срабатывает только при коде возврата wusa.exe, равном 3010. Если пакет вернул 0, скрипт завершится без перезагрузки даже при -Reboot Force. Это не ошибка реализации, а следствие того, что «установлено без требования перезагрузки» и «установлено, требуется перезагрузка» — разные коды.
Проверка после установки
Код возврата здесь плохой свидетель: он говорит, что пакет принят, а не что версия сменилась. Проверять нужно факт.
# до перезагрузки: пакет подготовлен
Get-Content "$env:ProgramData\Win11-26H2\Upgrade_*.log" -Tail 20
# после перезагрузки: версия действительно сменилась
Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' |
Select-Object CurrentBuild, UBR, DisplayVersion, ProductName
| Проверка | Ожидание |
|---|---|
CurrentBuild |
26300 (для 26H2) |
DisplayVersion |
26H2 |
| Журнал прогона | есть файл Upgrade_*.log, в нём строки о пакете и результате |
| Код возврата процесса | 0 — «подготовлено или делать нечего», не «версия сменилась» |
| Повторный прогон на цели | сообщение «already at target» и код 0 |
Подводные камни
- Документация расходится с релизом.
AGENTS.mdв разделе про установку утверждает: «Source install only — this repository has no releases» и «No checksums are published». На 30.10.2026gh release listотдаётv1.1.0с тремя артефактами, включаяSHA256SUMS.txt, и оба хеша у меня совпали. Верить нужно релизу и коду, а не абзацу, написанному до выпуска. -WhatIfесть только у 26H2. У скрипта 25H2 нет[CmdletBinding()], поэтому-WhatIfне существует: вызов с этим флагом — ошибка параметра, а не «тихий прогон». README в примерах для 25H2 его упоминает; проверять надоGet-Helpна фактическом файле.- Параметров из README может не быть. Для 25H2 README показывает
-ForceRebootи-NoRestart, которых скрипт не объявляет: вызов с ними падает.AGENTS.mdэто называет прямо. - Код 0 не доказывает обновление. Сборка меняется на перезагрузке. Хост, записанный в отчёт как «обновлён» по коду 0, может остаться на прежней версии до перезагрузки.
- Нет отката. Ни удаления, ни откота пакета в наборе нет; в README автоматический откат числится только планом. Импровизировать с удалением пакета на рабочем хосте нельзя.
- Путь установки не исполнялся при разработке. В заметках к релизу сказано прямо: проверены решения, цепочка загрузки и сами пакеты, а вызов
wusa.exeна живом хосте не выполнялся. Это означает, что первый боевой прогон — это и есть первая проверка установки. - BITS без запасного пути. Если служба BITS есть, но работает плохо, все попытки пойдут через неё: переключения на HTTP внутри попытки нет.
- Пакета нет в каталоге обновлений Microsoft. Закреплённые адреса CDN — несущая конструкция, и они могут перестать отвечать. Страховка —
-PackagePathс сохранённой копией, у которой имя содержитKB5121794и токен архитектуры. - Лицензия ограничивает применение. PolyForm Noncommercial 1.0.0: для коммерческого использования в организации набор не годится без отдельного соглашения.
Чек-лист внедрения
- Зафиксировать исходное состояние:
CurrentBuild,UBR,DisplayVersion, выпуск, архитектура. - Проверить предусловия: права, политика выполнения, доступ к каталогу Microsoft на 443.
- Прогнать предполётный режим
-WhatIfна одном тестовом хосте и сверить, что он называет именно ту сборку и выпуск, которые ожидаются. - Выполнить установку с
-Reboot None— перезагрузку оставить на окно обслуживания. - Перезагрузить вручную и проверить
CurrentBuild = 26300иDisplayVersion = 26H2. - Сохранить журнал прогона в тикет или базу знаний — он и есть доказательство.
- Только после успеха на одном хосте расширять на группу, при необходимости используя
-PackagePathс локальной копией.
Критерий «работает»: после перезагрузки сборка равна целевой, журнал содержит строки о загрузке и проверке подписи, повторный прогон сообщает «already at target» и завершается кодом 0.
Отдельно про смысл тестов. Они не проверяют, что пакет установился: установка в тестах не выполняется вообще. Проверяются решения — как скрипт ведёт себя при целевой сборке, поднятом минимуме, переопределённой архитектуре и подделанном выпуске. Каждая такая фикстура форсирует нужную ветку в копии скрипта и утверждает отсутствие маркеров загрузки и установки. Поэтому набор можно гонять на любом хосте, включая рабочий ноутбук, ничего не опасаясь, — и по этой же причине зелёный прогон не является доказательством, что боевая установка сработает.
FAQ
Чем это отличается от обычного обновления через Windows Update?
Тем, что вы управляете моментом и получаете журнал: пакет включения скачивается по закреплённому адресу, проверяется по SHA-1 и подписи, устанавливается отдельной командой, а перезагрузка откладывается. Windows Update делает то же самое, но без вашего участия и без проверяемых артефактов в руках.
Почему пакет весит сотни килобайт, а обновление — гигабайты?
Потому что компоненты новой версии уже лежат в системе: пакет включения переключает режим, а не приносит новые файлы. По этой же причине он требует, чтобы на хосте были установлены предварительные накопительные обновления.
Код возврата 0 — можно записывать хост в отчёт как обновлённый?
Нет. Ноль означает, что пакет принят и подготовлен либо что делать нечего. Сборка меняется на перезагрузке, поэтому проверять надо CurrentBuild = 26300 и DisplayVersion после неё.
Можно ли откатить обновление этими скриптами?
Нет. Откат и удаление пакета вне области набора: в README автоматический откат числится только планом. На рабочем хосте это делается штатными средствами Windows и с согласия владельца, а не импровизацией.
Работает ли -WhatIf на скрипте 25H2?
Нет, и это не опечатка: у файла 25H2 нет [CmdletBinding()], поэтому параметра -WhatIf не существует. Он есть только у скрипта 26H2, где объявлен через SupportsShouldProcess.
Почему пакет не нашёлся в каталоге обновлений Microsoft?
Он распространяется через Windows Update и WSUS, но не публикуется в Microsoft Update Catalog — поэтому адреса закреплены в скрипте. Если они перестанут отвечать, используется -PackagePath с сохранённой и проверенной копией.
Что делать, если загрузка идёт через BITS и постоянно падает?
Поднять -RetryCount и -RetryDelaySec помогает не всегда: переключения на HTTP внутри попытки нет. Надёжный обход — скачать пакет отдельно, сверить SHA-1 по имени файла, проверить подпись и передать через -PackagePath.
Итог
Набор делает одну вещь и делает её аккуратно: переводит подготовленный хост на следующую версию маленьким пакетом, отсекая неподходящие машины до скачивания и проверяя сам пакет двумя способами. Самое ценное в нём — не команды, а честность формулировок: код 0 назван «подготовлено», а не «обновлено», отсутствие откота названо прямо, а непроверенный путь установки отмечен в заметках к релизу. Если вы держите парк Windows 11 и хотите управлять моментом перехода, начинать стоит с -WhatIf на одном хосте: этот прогон ничего не пишет и сразу показывает, готова ли машина.
Цитата: Пакет включения экономит гигабайты, но не отменяет главного: обновление считается состоявшимся не по коду возврата, а по изменившейся сборке после перезагрузки.
Связанные материалы
- Windows-11-25H2-Update-Script — репозиторий — скрипты, README,
AGENTS.mdи тесты. - Релиз v1.1.0 — гейты, отпечатки пакетов и статус проверки.
- Горячие клавиши Windows — справочник по сочетаниям, сверенный с документацией Microsoft.
- Плоская сеть и блокировка SMB — что учесть в сети до массового обновления хостов.
- CVE-2026-111497: аудит Brotli тремя скриптами — пример подхода «проверка до и после изменения».
LLM Summary
- Тема:
Windows-11-25H2-Update-Script— набор скриптов, который ставит пакет включения Windows 11 и переводит хост на 25H2 (KB5054156) или 26H2 (KB5121794). - Состав:
Upgrade-Win11-To-25H2.ps1/.bat(версия 1.0.0, без изменений) иUpgrade-Win11-To-26H2.ps1/.batплюс 57 тестов Pester (версия 1.1.0). - Гейты 26H2: сборка 26100.9546+ на 24H2 или 26200.9550+ на 25H2; выпуски Home/Pro/Enterprise/Education/Enterprise multi-session/IoT Enterprise; LTSC и Windows Server отклоняются; 26H1 (28000+) отклоняется.
- Проверка пакета: закреплённый адрес CDN, SHA-1 из имени файла, подпись Authenticode, порог 100 000 байт; для
-PackagePathSHA-1 пропускается, подпись проверяется. - Параметры:
-Reboot Prompt|Force|None,-RetryCount 1–10(3),-RetryDelaySec 1–60(5),-Architecture,-PackagePath,-WhatIf(только у 26H2, черезCmdletBinding). - Коды возврата: 0 — пакет подготовлен либо делать нечего, 1 — любая ошибка; сборка меняется только после перезагрузки, проверять
CurrentBuild = 26300иDisplayVersion = 26H2. - Замеры: пакет x64 177 535 байт, ARM64 178 969 байт; три артефакта в релизе; SHA-256 обоих скриптов совпал с
SHA256SUMS.txt; параметры проверены разбором AST без запуска. - Ограничения: нет откота и удаления пакета, путь установки не исполнялся при разработке, BITS не имеет переключения на HTTP внутри попытки, пакета нет в каталоге обновлений Microsoft, лицензия PolyForm Noncommercial 1.0.0.
- Ссылки: https://github.com/paulmann/Windows-11-25H2-Update-Script, https://github.com/paulmann/Windows-11-25H2-Update-Script/releases/tag/v1.1.0
Промт для агента (установка и настройка)
Готовый промт для AI-агента: скопируйте блок целиком кнопкой и отдайте своему ассистенту. Шаги, предусловия и ожидаемые значения взяты из AGENTS.md репозитория — это инструкция автора для агентов, а не пересказ.
Задача: обновить хост Windows 11 до 26H2 пакетом включения KB5121794, не сорвав работу пользователей, и доказать результат проверкой.
Материалы:
- репозиторий: https://github.com/paulmann/Windows-11-25H2-Update-Script
- релиз: https://github.com/paulmann/Windows-11-25H2-Update-Script/releases/tag/v1.1.0
- контракт исполнителя: https://github.com/paulmann/Windows-11-25H2-Update-Script/blob/main/AGENTS.md
Предусловия (провал любой строки — остановка, а не предупреждение):
- Windows 11 24H2 сборка 26100.9546+ или 25H2 26200.9550+: reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v CurrentBuild и /v UBR
- административные права: net session >nul 2>&1 (exit 0 = elevated)
- архитектура x64 или ARM64: $env:PROCESSOR_ARCHITECTURE
- исходящий HTTPS к каталогу Microsoft: Test-NetConnection -ComputerName catalog.sf.dl.delivery.mp.microsoft.com -Port 443
- политика выполнения разрешает скрипты: Get-ExecutionPolicy -List
- окно обслуживания и право на перезагрузку (скрипты это не проверяют)
Установка и проверка:
git clone https://github.com/paulmann/Windows-11-25H2-Update-Script.git
cd Windows-11-25H2-Update-Script
Get-Help .\Upgrade-Win11-To-26H2.ps1 -Full
Порядок первого запуска:
1. Run checks above; record build, UBR and architecture.
2. Elevated session, reboot deferred: .\Upgrade-Win11-To-26H2.ps1 -Reboot None
3. Reboot manually inside a maintenance window.
4. Confirm CurrentBuild = 26300 and DisplayVersion = 26H2.
Предполёт без записи: .\Upgrade-Win11-To-26H2.ps1 -WhatIf (печатает сборку, выпуск, архитектуру, пакет и цель; ничего не пишет; при неопознанной архитектуре отказывается — передать -Architecture).
Локальная копия пакета: -PackagePath, имя файла должно содержать KB5121794 и токен архитектуры.
Запрещено:
- запускать на хосте, который используется людьми: перезагрузка прерывает сессии;
- считать код 0 доказательством обновления: сборка меняется только после перезагрузки;
- импровизировать с удалением или откатом пакета: в репозитории это не документировано;
- вызывать -ForceReboot или -NoRestart: таких параметров нет (они упомянуты в README для 25H2, но скрипт их не объявляет);
- ждать -WhatIf от скрипта 25H2: у него нет CmdletBinding и параметра не существует;
- подменять пакет файлом с другим именем: проверка SHA-1 берёт отпечаток из имени.
Что считать успехом: после перезагрузки CurrentBuild = 26300, DisplayVersion = 26H2, журнал %ProgramData%\Win11-26H2\Upgrade_*.log содержит строки о загрузке и проверке подписи, повторный прогон отвечает "already at target" и завершается кодом 0.