Обновление установочного носителя Windows с помощью динамического обновления
В этой статье объясняется, как получать и применять пакеты динамического обновления к существующим образам Windows перед развертыванием, а также содержатся Windows PowerShell скрипты, которые можно использовать для автоматизации этого процесса.
Корпоративный носитель доступен для каждого выпуска Windows в Центре обслуживания корпоративного лицензирования (VLSC) и других соответствующих каналах, таких как клиентский компонент Центра обновления Windows для бизнеса, Windows Server Update Services (WSUS) и Подписки Visual Studio. Вы можете использовать динамическое обновление, чтобы обеспечить наличие на устройствах Windows последних пакетов обновления компонентов в рамках обновления на месте при сохранении языковых пакетов и компонентов по запросу (FOD), которые могли быть установлены ранее. Динамическое обновление также устраняет необходимость установки отдельного обновления качества в рамках процесса обновления на месте.
Динамическое обновление
При каждом запуске установки обновления компонентов (с носителя или среды, подключенной к клиентский компонент Центра обновления Windows), одним из первых шагов является динамическое обновление. Программа установки Windows связывается с конечной точкой Майкрософт для получения пакетов динамического обновления, а затем применяет эти обновления к установочному носителю операционной системы. Пакеты обновлений включают следующие типы обновлений:
- Обновления для Setup.exe двоичных файлов или других файлов, используемых программой установки для обновления компонентов
- Обновления для "безопасной операционной системы" (SafeOS), используемой для среды восстановления Windows
- Обновления в стек обслуживания, необходимый для завершения обновления компонентов Дополнительные сведения см. в разделе Обновления стека обслуживания.
- Последнее накопительное (качественное) обновление
- Обновления к применимым драйверам, уже опубликованным производителями, специально предназначенными для динамического обновления
Динамическое обновление сохраняет языковые пакеты и пакеты компонентов по запросу, повторно запрашивая их.
Устройства должны иметь возможность подключения к Интернету, чтобы получить динамические Обновления. В некоторых средах это не вариант для получения динамической Обновления. Вы по-прежнему можете выполнить обновление компонентов на основе мультимедиа, получив пакеты динамического обновления и применив его к образу перед запуском установки на устройстве.
Получение пакетов динамического обновления
Пакеты динамического обновления можно получить из каталога Центра обновления Майкрософт. На этом сайте используйте строку поиска в правом верхнем углу, чтобы найти пакеты динамического обновления для определенного выпуска. Различные пакеты динамического обновления могут не присутствовать в результатах одного поиска, поэтому вам может потребоваться выполнить поиск с разными ключевыми словами, чтобы найти все обновления. Проверьте различные части результатов, чтобы убедиться, что вы определили необходимые файлы. В следующих таблицах показаны ключевые значения для поиска или поиска в результатах.
Пакеты динамического обновления Windows Server 2025 г.
Заголовок может различать каждый динамический пакет. В последние накопительные обновления внедрен стек обслуживания. Стек обслуживания публикуется только при необходимости для данного накопительного обновления.
Обновление пакетов | Title |
---|---|
Безопасное динамическое обновление ОС | ГГГ-ММ Безопасное динамическое обновление ОС для серверной операционной системы Майкрософт версии 24H2 |
Настройка динамического обновления | ГгГГ-ММ: динамическое обновление для операционной системы сервера Майкрософт версии 24H2 |
Последнее накопительное обновление | ГГГГ-ММ накопительное обновление для серверной операционной системы Майкрософт версии 24H2 |
Динамическое обновление стека обслуживания | Обновление стека обслуживания ггГГ-ММ для серверной операционной системы Майкрософт версии 24H2 |
пакеты динамического обновления Windows Server версии 23H2
Заголовок может различать каждый динамический пакет. В последние накопительные обновления внедрен стек обслуживания. Стек обслуживания публикуется только при необходимости для данного накопительного обновления. Azure Stack HCI версии 23H2 имеет аналогичный формат.
Обновление пакетов | Title |
---|---|
Безопасное динамическое обновление ОС | YYYY-MM Безопасное динамическое обновление ОС для серверной операционной системы Майкрософт версии 23H2 |
Настройка динамического обновления | ГгГГ-ММ: динамическое обновление установки для операционной системы сервера Майкрософт версии 23H2 |
Последнее накопительное обновление | ГгГГ-ММ накопительное обновление для серверной операционной системы Майкрософт версии 23H2 |
Динамическое обновление стека обслуживания | ГгГГ-ММ обновление стека обслуживания для серверной операционной системы Майкрософт версии 23H2 |
Пакеты динамического обновления Azure Stack HCI версии 22H2
Для различения каждого динамического пакета требуется название, продукт и описание . В последнее накопительное обновление внедрен стек обслуживания. Стек обслуживания публикуется отдельно, только если это необходимо в качестве необходимого условия для данного накопительного обновления.
Обновление пакетов | Title | Продукт | Описание |
---|---|---|---|
Безопасное динамическое обновление ОС | Динамическое обновление ггГГ-ММ для серверной операционной системы Майкрософт, версия 22H2 | Динамическое обновление безопасной ОС Windows | ComponentUpdate |
Настройка динамического обновления | Динамическое обновление ггГГ-ММ для серверной операционной системы Майкрософт, версия 22H2 | динамическое обновление Windows 10 и более поздних версий | SetupUpdate |
Последнее накопительное обновление | ГГГГ-ММ накопительное обновление для серверной операционной системы Майкрософт, версия 22H2 | ||
Динамическое обновление стека обслуживания | Обновление стека обслуживания ггГГ-ММ для серверной операционной системы Майкрософт, версия 22H2 |
Windows Server 2022 более поздних пакетов динамического обновления
Для различения каждого динамического пакета требуется название, продукт и описание . В последнее накопительное обновление внедрен стек обслуживания. Стек обслуживания публикуется отдельно, только если это необходимо в качестве необходимого условия для данного накопительного обновления.
Обновление пакетов | Title | Продукт | Описание |
---|---|---|---|
Безопасное динамическое обновление ОС | Динамическое обновление ГГГГ-ММ для серверной операционной системы Майкрософт, версия 21H2 | Динамическое обновление безопасной ОС Windows | ComponentUpdate |
Настройка динамического обновления | Динамическое обновление ГГГГ-ММ для серверной операционной системы Майкрософт, версия 21H2 | динамическое обновление Windows 10 и более поздних версий | SetupUpdate |
Последнее накопительное обновление | ГгГГ-ММ Накопительное обновление для серверной операционной системы Майкрософт, версия 21H2 | ||
Динамическое обновление стека обслуживания | Обновление стека обслуживания ггГГ-ММ для серверной операционной системы Майкрософт, версия 21H2 |
пакеты динамического обновления Windows 11 версии 22H2 и более поздних версий
Заголовок может различать каждый динамический пакет. В последние накопительные обновления внедрен стек обслуживания. Стек обслуживания публикуется только при необходимости для данного накопительного обновления. Следующие заголовки предназначены для Windows 11 версии 22H2. Windows 11 версии 23H2 и версии 24H2 имеют аналогичный формат:
Обновление пакетов | Title |
---|---|
Безопасное динамическое обновление ОС | YYYY-MM Безопасное динамическое обновление ОС для Windows 11 версии 22H2 |
Настройка динамического обновления | Динамическое обновление установки ггГГ-ММ для Windows 11 версии 22H2 |
Последнее накопительное обновление | ГгГГ-ММ накопительное обновление для Windows 11 версии 22H2 |
Динамическое обновление стека обслуживания | Обновление стека обслуживания ггГГ-ММ для Windows 11 версии 22H2 |
пакеты динамического обновления Windows 11 версии 21H2
Для различения каждого динамического пакета требуется название, продукт и описание . В последнее накопительное обновление внедрен стек обслуживания. Стек обслуживания публикуется отдельно, только если это необходимо в качестве необходимого условия для данного накопительного обновления.
Обновление пакетов | Title | Продукт | Описание |
---|---|---|---|
Безопасное динамическое обновление ОС | Динамическое обновление ггГГ-ММ для Windows 11 | Динамическое обновление безопасной ОС Windows | ComponentUpdate |
Настройка динамического обновления | Динамическое обновление ггГГ-ММ для Windows 11 | динамическое обновление Windows 10 и более поздних версий | SetupUpdate |
Последнее накопительное обновление | Накопительное обновление ггГГ-ММ для Windows 11 | ||
Динамическое обновление стека обслуживания | Обновление стека обслуживания ггГГ-ММ для Windows 11 версии 21H2 |
пакеты динамического обновления Windows 10 версии 22H2
Для различения каждого динамического пакета требуется название, продукт и описание . В последнее накопительное обновление внедрен стек обслуживания. Стек обслуживания публикуется отдельно, только если это необходимо в качестве необходимого условия для данного накопительного обновления.
Обновление пакетов | Title | Продукт | Описание |
---|---|---|---|
Безопасное динамическое обновление ОС | Динамическое обновление ГГГГ-ММ для Windows 10 версии 22H2 | Динамическое обновление безопасной ОС Windows | ComponentUpdate |
Настройка динамического обновления | Динамическое обновление ГГГГ-ММ для Windows 10 версии 22H2 | динамическое обновление Windows 10 и более поздних версий | SetupUpdate |
Последнее накопительное обновление | Накопительное обновление ггГГ-ММ для Windows 10 версии 22H2 | ||
Динамическое обновление стека обслуживания | Обновление стека обслуживания ггГГ-ММ для Windows 10 версии 22H2 |
Если вы хотите настроить образ с помощью дополнительных языков или функций по запросу, скачайте дополнительные ISO-файлы мультимедиа из Центра обслуживания корпоративного лицензирования. Например, если динамическое обновление будет отключено для ваших устройств и пользователям требуются определенные функции по запросу, их можно предварительно включить в образ.
Обновление установочного носителя Windows
Правильное обновление установочного носителя включает в себя множество действий, выполняемых с несколькими разными целевыми объектами (файлами образов). Некоторые действия повторяются в разных целевых объектах. К целевым файлам образов относятся:
- Среда предустановки Windows (WinPE): небольшая операционная система, используемая для установки, развертывания и восстановления операционных систем Windows.
- Среда восстановления Windows (WinRE): исправит распространенные причины незагрузимых операционных систем. WinRE основан на WinPE и может быть настроен с помощью дополнительных драйверов, языков, необязательных пакетов и других средств для устранения неполадок или диагностики.
- Операционная система Windows: один или несколько выпусков Windows, хранящихся в \sources\install.wim
- Установочный носитель Windows: полная коллекция файлов и папок на установочном носителе Windows. Например, папка \sources, папка \boot, Setup.exe и т. д.
В этой таблице показана правильная последовательность для применения различных задач к файлам. Например, полная последовательность начинается с добавления обновления стека обслуживания в WinRE (1) и завершается добавлением диспетчера загрузки из WinPE на новый носитель (28).
Задача | WinRE (winre.wim) | Операционная система (install.wim) | WinPE (boot.wim) | Новый носитель |
---|---|---|---|---|
Добавление обновления стека обслуживания с помощью последнего накопительного обновления | 1 | 9 | 17 | |
Добавление языкового пакета | 2 | 10 | 18 | |
Добавление локализованных необязательных пакетов | 3 | 19 | ||
Добавление поддержки шрифтов | 4 | 20 | ||
Добавление преобразования текста в речь | 5 | 21 | ||
Обновление Lang.ini | 22 | |||
Добавление функций по запросу | 11 | |||
Добавление необязательных компонентов | 12 | |||
Добавление безопасного динамического обновления ОС | 6 | |||
Добавление динамического обновления установки | 26 | |||
Добавление Setup.exe и setuphost.exe из WinPE | 27 | |||
Добавление диспетчера загрузки из WinPE | 28 | |||
Добавление последнего накопительного обновления | 13 | 23 | ||
Очистка изображения | 7 | 14 | 24 | |
Добавление накопительных обновлений .NET и .NET | 15 | |||
Экспорт изображения | 8 | 16 | 25 |
Примечание.
Начиная с февраля 2021 г. последнее накопительное обновление и обновление стека обслуживания объединяется и распространяется в каталоге Центра обновления Майкрософт в виде нового объединенного накопительного обновления. Для шагов 1, 9 и 17, требующих обновления стека обслуживания для обновления установочного носителя, следует использовать объединенное накопительное обновление. Дополнительные сведения о объединенном накопительном обновлении см. в разделе Обновления стека обслуживания.
Примечание.
Корпорация Майкрософт удаляет компонент Flash из Windows через KB4577586: Обновление для удаления Adobe Flash Player. Вы также можете удалить Flash в любое время, развернув обновление в KB4577586 (доступно в каталоге) между шагами 20 и 21. Начиная с июля 2021 года, KB4577586, "Обновление для удаления Adobe Flash Player" будет включено в последнее накопительное обновление для Windows 10 версии 1607 и 1507. Обновление также будет включено в ежемесячный накопительный пакет и обновление только для системы безопасности для Windows 8.1, Windows Server 2012 и Windows Embedded 8 Standard. Дополнительные сведения см. в разделе Обновление окончания поддержки Adobe Flash Player.
Несколько выпусков Windows
Файл операционной системы main (install.wim) может содержать несколько выпусков Windows. Возможно, для его развертывания на основе индекса требуется только обновление для определенного выпуска. Или может потребоваться обновление для всех выпусков. Кроме того, убедитесь, что языки установлены перед компонентом по запросу, а последнее накопительное обновление всегда применяется последним.
Дополнительные языки и функции
Вам не нужно добавлять в образ дополнительные языки и функции, чтобы выполнить обновления, но это возможность настроить образ с дополнительными языками, дополнительными компонентами и функциями по запросу, помимо того, что находится в начальном образе. При добавлении дополнительных языков и функций важно внести эти изменения в правильном порядке: сначала применить обновления стека обслуживания, а затем добавить язык, затем добавить компоненты и, наконец, последнее накопительное обновление. Предоставленный пример скрипта устанавливает второй язык (в данном случае японский (ja-JP)). Так как этот язык поддерживается lp.cab, добавлять языковой пакет не требуется. Японский язык добавляется как в main операционную систему, так и в среду восстановления, чтобы позволить пользователю просматривать экраны восстановления на японском языке. Сюда входит добавление локализованных версий пакетов, установленных в данный момент в образе восстановления.
Необязательные компоненты вместе с функцией .NET можно установить в автономном режиме. Однако при этом создаются ожидающие операции, требующие перезапуска устройства. В результате вызов для очистки образа завершится ошибкой. Существует два способа избежать сбоя очистки. Один из вариантов — пропустить шаг очистки образа, хотя это приводит к большему размеру install.wim. Другой вариант — установить .NET и необязательные компоненты на шаге после очистки, но перед экспортом. Это параметр в примере скрипта. Это позволит вам начать с исходного файла install.wim (без ожидающих действий) при следующем обслуживании или обновлении образа (например, в следующем месяце).
Накопительные обновления контрольных точек
Начиная с Windows 11 версии 24H2 и Windows Server 2025, последнее накопительное обновление может иметь обязательное накопительное обновление, которое необходимо установить в первую очередь. Эти обновления называются накопительными обновлениями контрольных точек. В этих случаях различия на уровне файлов накопительного обновления основаны на предыдущем накопительном обновлении, а не на выпуске Windows RTM. Преимущество заключается в меньшем пакете обновления и более быстрой установке. При получении последнего накопительного обновления из каталога Центра обновления Майкрософт накопительные обновления контрольных точек доступны с помощью кнопки скачивания. Кроме того, дополнительные сведения содержатся в статье база знаний накопительного обновления.
Чтобы установить контрольные точки при обслуживании ОС Windows (шаги 9 & 12) и WinPE (шаги 17 & 23), вызовите Add-WindowsPackage
целевое накопительное обновление. Папка из -PackagePath
используется для обнаружения и установки одной или нескольких контрольных точек при необходимости. В папке должны находиться только целевые накопительные обновления и накопительные обновления контрольных -PackagePath
точек. Пакеты накопительного обновления с редакцией <= целевое накопительное обновление обрабатываются. Если вы не настраиваете образ с дополнительными языками и (или) дополнительными функциями, то для шагов 9 & 17 выше можно использовать отдельные вызовы ( Add-WindowsPackage
сначала накопительные обновления контрольных точек). Отдельные вызовы нельзя использовать для шагов 12 и 23.
Windows PowerShell скрипты для применения динамической Обновления к существующему образу
Эти примеры предназначены только для иллюстрации и поэтому не обрабатывают ошибки. Сценарий предполагает, что следующие пакеты хранятся локально в этой структуре папок:
Папка | Описание |
---|---|
C:\mediaRefresh | Родительская папка, содержащая скрипт PowerShell |
C:\mediaRefresh\oldMedia | Папка, содержащая исходный носитель, который будет обновлен. Например, содержит Setup.exe и папку \sources. |
C:\mediaRefresh\newMedia | Папка, которая будет содержать обновленный носитель. Он копируется из \oldMedia, а затем используется в качестве целевого объекта для всех операций обновления и очистки. |
Get started
Скрипт начинается с объявления глобальных переменных и создания папок для подключения образов. Затем создайте копию исходного носителя из \oldMedia в \newMedia, сохраняя исходный носитель на случай ошибки скрипта и необходимо начать с известного состояния. Кроме того, он предоставляет сравнение старых и новых носителей для оценки изменений. Чтобы убедиться, что новые обновления мультимедиа не доступны только для чтения. Скрипт также демонстрирует добавление дополнительных языков, функций по запросу и дополнительных компонентов. Они не являются обязательными, но добавляются для выделения, когда они должны быть добавлены в последовательности. Начиная с Windows 11 версии 21H2, ISO-файл языкового пакета (LANGPACK) заменен ISO-файлом "Компоненты по запросу". Языковые пакеты и пакеты среды предустановки \Windows являются частью ISO функций по запросу. Кроме того, путь к языку ос main и дополнительным функциям перемещен в папку \LanguagesAndOptionalFeatures, а не в корневой каталог. Если вы используете этот скрипт для Windows 10, измените его для подключения и использования ISO языкового пакета (LANGPACK).
#Requires -RunAsAdministrator
function Get-TS { return "{0:HH:mm:ss}" -f [DateTime]::Now }
Write-Output "$(Get-TS): Starting media refresh"
# Declare Dynamic Update packages. A dedicated folder is used for the latest cumulative update, and as needed
# checkpoint cumulative updates.
$LCU_PATH = "C:\mediaRefresh\packages\CU\LCU.msu"
$SETUP_DU_PATH = "C:\mediaRefresh\packages\Other\Setup_DU.cab"
$SAFE_OS_DU_PATH = "C:\mediaRefresh\packages\Other\SafeOS_DU.cab"
$DOTNET_CU_PATH = "C:\mediaRefresh\packages\Other\DotNet_CU.msu"
# Declare media for FOD and LPs
$FOD_ISO_PATH = "C:\mediaRefresh\packages\CLIENT_LOF_PACKAGES_OEM.iso"
# Array of Features On Demand for main OS
# This is optional to showcase where these are added
$FOD = @(
'XPS.Viewer~~~~0.0.1.0'
)
# Array of Legacy Features for main OS
# This is optional to showcase where these are added
$OC = @(
'MediaPlayback'
'WindowsMediaPlayer'
)
# Mount the Features on Demand ISO
Write-Output "$(Get-TS): Mounting FOD ISO"
$FOD_ISO_DRIVE_LETTER = (Mount-DiskImage -ImagePath $FOD_ISO_PATH -ErrorAction stop | Get-Volume).DriveLetter
$FOD_PATH = $FOD_ISO_DRIVE_LETTER + ":\LanguagesAndOptionalFeatures"
# Declare language for showcasing adding optional localized components
$LANG = "ja-jp"
$LANG_FONT_CAPABILITY = "jpan"
# Declare language related cabs
$WINPE_OC_PATH = "$FOD_ISO_DRIVE_LETTER`:\Windows Preinstallation Environment\x64\WinPE_OCs"
$WINPE_OC_LANG_PATH = "$WINPE_OC_PATH\$LANG"
$WINPE_OC_LANG_CABS = Get-ChildItem $WINPE_OC_LANG_PATH -Name
$WINPE_OC_LP_PATH = "$WINPE_OC_LANG_PATH\lp.cab"
$WINPE_FONT_SUPPORT_PATH = "$WINPE_OC_PATH\WinPE-FontSupport-$LANG.cab"
$WINPE_SPEECH_TTS_PATH = "$WINPE_OC_PATH\WinPE-Speech-TTS.cab"
$WINPE_SPEECH_TTS_LANG_PATH = "$WINPE_OC_PATH\WinPE-Speech-TTS-$LANG.cab"
$OS_LP_PATH = "$FOD_PATH\Microsoft-Windows-Client-Language-Pack_x64_$LANG.cab"
# Declare folders for mounted images and temp files
$MEDIA_OLD_PATH = "C:\mediaRefresh\oldMedia\Ge\client_professional_en-us"
$MEDIA_NEW_PATH = "C:\mediaRefresh\newMedia"
$WORKING_PATH = "C:\mediaRefresh\temp"
$MAIN_OS_MOUNT = "C:\mediaRefresh\temp\MainOSMount"
$WINRE_MOUNT = "C:\mediaRefresh\temp\WinREMount"
$WINPE_MOUNT = "C:\mediaRefresh\temp\WinPEMount"
# Create folders for mounting images and storing temporary files
New-Item -ItemType directory -Path $WORKING_PATH -ErrorAction Stop | Out-Null
New-Item -ItemType directory -Path $MAIN_OS_MOUNT -ErrorAction stop | Out-Null
New-Item -ItemType directory -Path $WINRE_MOUNT -ErrorAction stop | Out-Null
New-Item -ItemType directory -Path $WINPE_MOUNT -ErrorAction stop | Out-Null
# Keep the original media, make a copy of it for the new, updated media.
Write-Output "$(Get-TS): Copying original media to new media path"
Copy-Item -Path $MEDIA_OLD_PATH"\*" -Destination $MEDIA_NEW_PATH -Force -Recurse -ErrorAction stop | Out-Null
Get-ChildItem -Path $MEDIA_NEW_PATH -Recurse | Where-Object { -not $_.PSIsContainer -and $_.IsReadOnly } | ForEach-Object { $_.IsReadOnly = $false }
Обновление WinRE и каждой main ос Windows
Скрипт обновляет каждый выпуск Windows в файле операционной системы main (install.wim). Для каждого выпуска подключен образ ОС main.
Для первого образа Winre.wim копируется в рабочую папку и подключается. Затем он применяет стек обслуживания через последнее накопительное обновление, так как его компоненты используются для обновления других компонентов. В зависимости от выпуска Windows, который вы обновляете, существует два разных подхода к обновлению стека обслуживания. Первый подход заключается в использовании объединенного накопительного обновления. Это относится к выпускам Windows, которые предоставляют объединенное накопительное обновление, включающее обновления стека обслуживания (то есть объединяются SSU и LCU). примерами являются Windows 11 версии 21H2 и Windows 11 версии 22H2. В этих случаях обновление стека обслуживания не публикуется отдельно; На этом шаге следует использовать объединенное накопительное обновление. Однако в редких случаях может произойть критическое изменение в объединенном формате накопительного обновления, что требует публикации автономного обновления стека обслуживания и установки сначала перед установкой объединенного накопительного обновления. Так как скрипт при необходимости добавляет японский язык, он добавляет языковой пакет в образ и устанавливает японские версии всех дополнительных пакетов, уже установленных в Winre.wim. Затем применяется пакет динамического обновления безопасной ОС. Она завершается очисткой и экспортом образа, чтобы уменьшить размер изображения.
Затем для подключенного образа ОС скрипт запускается с применением стека обслуживания с помощью последнего накопительного обновления. Затем добавляется поддержка японского языка, а затем функции японского языка. В отличие от пакетов динамического обновления, он использует для Add-WindowsCapability
добавления этих функций. Полный список таких функций и связанные с ними имена возможностей см. в разделе Доступные функции по запросу. Настало время включить другие необязательные компоненты или добавить другие функции по запросу. Если с такой функцией связано накопительное обновление (например, .NET), это время для его применения. Затем скрипт пытается очистить образ, а затем последний шаг для применения последнего накопительного обновления. Важно применить последнее накопительное обновление, чтобы убедиться, что функции по запросу, необязательные компоненты и языки обновляются с исходного состояния выпуска. Функция .NET — это исключение, которое добавляется вместе с накопительным обновлением. Наконец, скрипт экспортирует изображение.
Этот процесс повторяется для каждого выпуска Windows в файле операционной системы main. Чтобы уменьшить размер, файл Winre.wim с первого образа сохраняется и используется для обновления каждого последующего выпуска Windows. Это уменьшает окончательный размер install.wim.
#
# Update each main OS Windows image including the Windows Recovery Environment (WinRE)
#
# Get the list of images contained within the main OS
$WINOS_IMAGES = Get-WindowsImage -ImagePath $MEDIA_NEW_PATH"\sources\install.wim"
Foreach ($IMAGE in $WINOS_IMAGES)
{
# first mount the main OS image
Write-Output "$(Get-TS): Mounting main OS, image index $($IMAGE.ImageIndex)"
Mount-WindowsImage -ImagePath $MEDIA_NEW_PATH"\sources\install.wim" -Index $IMAGE.ImageIndex -Path $MAIN_OS_MOUNT -ErrorAction stop| Out-Null
if ($IMAGE.ImageIndex -eq "1")
{
#
# update Windows Recovery Environment (WinRE) within this OS image
#
Copy-Item -Path $MAIN_OS_MOUNT"\windows\system32\recovery\winre.wim" -Destination $WORKING_PATH"\winre.wim" -Force -ErrorAction stop | Out-Null
Write-Output "$(Get-TS): Mounting WinRE"
Mount-WindowsImage -ImagePath $WORKING_PATH"\winre.wim" -Index 1 -Path $WINRE_MOUNT -ErrorAction stop | Out-Null
# Add servicing stack update (Step 1 from the table)
Write-Output "$(Get-TS): Adding package $LCU_PATH to WinRE"
try
{
Add-WindowsPackage -Path $WINRE_MOUNT -PackagePath $LCU_PATH | Out-Null
}
Catch
{
$theError = $_
Write-Output "$(Get-TS): $theError"
if ($theError.Exception -like "*0x8007007e*")
{
Write-Warning "$(Get-TS): Failed with error 0x8007007e. This failure is a known issue with combined cumulative update, we can ignore."
}
else
{
throw
}
}
#
# Optional: Add the language to recovery environment
#
# Install lp.cab cab
Write-Output "$(Get-TS): Adding package $WINPE_OC_LP_PATH to WinRE"
Add-WindowsPackage -Path $WINRE_MOUNT -PackagePath $WINPE_OC_LP_PATH -ErrorAction stop | Out-Null
# Install language cabs for each optional package installed
$WINRE_INSTALLED_OC = Get-WindowsPackage -Path $WINRE_MOUNT
Foreach ($PACKAGE in $WINRE_INSTALLED_OC)
{
if ( ($PACKAGE.PackageState -eq "Installed") -and ($PACKAGE.PackageName.startsWith("WinPE-")) -and ($PACKAGE.ReleaseType -eq "FeaturePack") )
{
$INDEX = $PACKAGE.PackageName.IndexOf("-Package")
if ($INDEX -ge 0)
{
$OC_CAB = $PACKAGE.PackageName.Substring(0, $INDEX) + "_" + $LANG + ".cab"
if ($WINPE_OC_LANG_CABS.Contains($OC_CAB))
{
$OC_CAB_PATH = Join-Path $WINPE_OC_LANG_PATH $OC_CAB
Write-Output "$(Get-TS): Adding package $OC_CAB_PATH to WinRE"
Add-WindowsPackage -Path $WINRE_MOUNT -PackagePath $OC_CAB_PATH -ErrorAction stop | Out-Null
}
}
}
}
# Add font support for the new language
if ( (Test-Path -Path $WINPE_FONT_SUPPORT_PATH) )
{
Write-Output "$(Get-TS): Adding package $WINPE_FONT_SUPPORT_PATH to WinRE"
Add-WindowsPackage -Path $WINRE_MOUNT -PackagePath $WINPE_FONT_SUPPORT_PATH -ErrorAction stop | Out-Null
}
# Add TTS support for the new language
if (Test-Path -Path $WINPE_SPEECH_TTS_PATH)
{
if ( (Test-Path -Path $WINPE_SPEECH_TTS_LANG_PATH) )
{
Write-Output "$(Get-TS): Adding package $WINPE_SPEECH_TTS_PATH to WinRE"
Add-WindowsPackage -Path $WINRE_MOUNT -PackagePath $WINPE_SPEECH_TTS_PATH -ErrorAction stop | Out-Null
Write-Output "$(Get-TS): Adding package $WINPE_SPEECH_TTS_LANG_PATH to WinRE"
Add-WindowsPackage -Path $WINRE_MOUNT -PackagePath $WINPE_SPEECH_TTS_LANG_PATH -ErrorAction stop | Out-Null
}
}
# Add Safe OS
Write-Output "$(Get-TS): Adding package $SAFE_OS_DU_PATH to WinRE"
Add-WindowsPackage -Path $WINRE_MOUNT -PackagePath $SAFE_OS_DU_PATH -ErrorAction stop | Out-Null
# Perform image cleanup
Write-Output "$(Get-TS): Performing image cleanup on WinRE"
DISM /image:$WINRE_MOUNT /cleanup-image /StartComponentCleanup /ResetBase /Defer | Out-Null
if ($LastExitCode -ne 0)
{
throw "Error: Failed to perform image cleanup on WinRE. Exit code: $LastExitCode"
}
# Dismount
Dismount-WindowsImage -Path $WINRE_MOUNT -Save -ErrorAction stop | Out-Null
# Export
Write-Output "$(Get-TS): Exporting image to $WORKING_PATH\winre.wim"
Export-WindowsImage -SourceImagePath $WORKING_PATH"\winre.wim" -SourceIndex 1 -DestinationImagePath $WORKING_PATH"\winre2.wim" -ErrorAction stop | Out-Null
}
Copy-Item -Path $WORKING_PATH"\winre2.wim" -Destination $MAIN_OS_MOUNT"\windows\system32\recovery\winre.wim" -Force -ErrorAction stop | Out-Null
#
# update Main OS
#
# Add servicing stack update (Step 17 from the table). Unlike WinRE and WinPE, we don't need to check for error 0x8007007e
Write-Output "$(Get-TS): Adding package $LCU_PATH to main OS, index $($IMAGE.ImageIndex)"
Add-WindowsPackage -Path $MAIN_OS_MOUNT -PackagePath $LCU_PATH | Out-Null
# Optional: Add language to main OS and corresponding language experience Features on Demand
Write-Output "$(Get-TS): Adding package $OS_LP_PATH to main OS, index $($IMAGE.ImageIndex)"
Add-WindowsPackage -Path $MAIN_OS_MOUNT -PackagePath $OS_LP_PATH -ErrorAction stop | Out-Null
Write-Output "$(Get-TS): Adding language FOD: Language.Fonts.Jpan~~~und-JPAN~0.0.1.0 to main OS, index $($IMAGE.ImageIndex)"
Add-WindowsCapability -Name "Language.Fonts.$LANG_FONT_CAPABILITY~~~und-$LANG_FONT_CAPABILITY~0.0.1.0" -Path $MAIN_OS_MOUNT -Source $FOD_PATH -ErrorAction stop | Out-Null
Write-Output "$(Get-TS): Adding language FOD: Language.Basic~~~$LANG~0.0.1.0 to main OS, index $($IMAGE.ImageIndex)"
Add-WindowsCapability -Name "Language.Basic~~~$LANG~0.0.1.0" -Path $MAIN_OS_MOUNT -Source $FOD_PATH -ErrorAction stop | Out-Null
Write-Output "$(Get-TS): Adding language FOD: Language.OCR~~~$LANG~0.0.1.0 to main OS, index $($IMAGE.ImageIndex)"
Add-WindowsCapability -Name "Language.OCR~~~$LANG~0.0.1.0" -Path $MAIN_OS_MOUNT -Source $FOD_PATH -ErrorAction stop | Out-Null
Write-Output "$(Get-TS): Adding language FOD: Language.Handwriting~~~$LANG~0.0.1.0 to main OS, index $($IMAGE.ImageIndex)"
Add-WindowsCapability -Name "Language.Handwriting~~~$LANG~0.0.1.0" -Path $MAIN_OS_MOUNT -Source $FOD_PATH -ErrorAction stop | Out-Null
Write-Output "$(Get-TS): Adding language FOD: Language.TextToSpeech~~~$LANG~0.0.1.0 to main OS, index $($IMAGE.ImageIndex)"
Add-WindowsCapability -Name "Language.TextToSpeech~~~$LANG~0.0.1.0" -Path $MAIN_OS_MOUNT -Source $FOD_PATH -ErrorAction stop | Out-Null
Write-Output "$(Get-TS): Adding language FOD: Language.Speech~~~$LANG~0.0.1.0 to main OS, index $($IMAGE.ImageIndex)"
Add-WindowsCapability -Name "Language.Speech~~~$LANG~0.0.1.0" -Path $MAIN_OS_MOUNT -Source $FOD_PATH -ErrorAction stop | Out-Null
# Optional: Add additional Features On Demand
For ( $index = 0; $index -lt $FOD.count; $index++)#
{
Write-Output "$(Get-TS): Adding $($FOD[$index]) to main OS, index $($IMAGE.ImageIndex)"
Add-WindowsCapability -Name $($FOD[$index]) -Path $MAIN_OS_MOUNT -Source $FOD_PATH -ErrorAction stop | Out-Null
}
# Optional: Add Legacy Features
For ( $index = 0; $index -lt $OC.count; $index++)
{
Write-Output "$(Get-TS): Adding $($OC[$index]) to main OS, index $($IMAGE.ImageIndex)"
DISM /Image:$MAIN_OS_MOUNT /Enable-Feature /FeatureName:$($OC[$index]) /All | Out-Null
if ($LastExitCode -ne 0)
{
throw "Error: Failed to add $($OC[$index]) to main OS, index $($IMAGE.ImageIndex). Exit code: $LastExitCode"
}
}
# Add latest cumulative update
Write-Output "$(Get-TS): Adding package $LCU_PATH to main OS, index $($IMAGE.ImageIndex)"
Add-WindowsPackage -Path $MAIN_OS_MOUNT -PackagePath $LCU_PATH -ErrorAction stop | Out-Null
# Perform image cleanup. Some Optional Components might require the image to be booted, and thus
# image cleanup may fail. We'll catch and handle as a warning.
Write-Output "$(Get-TS): Performing image cleanup on main OS, index $($IMAGE.ImageIndex)"
DISM /image:$MAIN_OS_MOUNT /cleanup-image /StartComponentCleanup | Out-Null
if ($LastExitCode -ne 0)
{
if ($LastExitCode -eq -2146498554)
{
# We hit 0x800F0806 CBS_E_PENDING. We will ignore this with a warning
# This is likely due to legacy components being added that require online operations.
Write-Warning "$(Get-TS): Failed to perform image cleanup on main OS, index $($IMAGE.ImageIndex). Exit code: $LastExitCode. The operation cannot be performed until pending servicing operations are completed. The image must be booted to complete the pending servicing operation."
}
else
{
throw "Error: Failed to perform image cleanup on main OS, index $($IMAGE.ImageIndex). Exit code: $LastExitCode"
}
}
# Finally, we'll add .NET 3.5 and the .NET cumulative update
Write-Output "$(Get-TS): Adding NetFX3~~~~ to main OS, index $($IMAGE.ImageIndex)"
Add-WindowsCapability -Name "NetFX3~~~~" -Path $MAIN_OS_MOUNT -Source $FOD_PATH -ErrorAction stop | Out-Null
# Add .NET Cumulative Update
Write-Output "$(Get-TS): Adding package $DOTNET_CU_PATH to main OS, index $($IMAGE.ImageIndex)"
Add-WindowsPackage -Path $MAIN_OS_MOUNT -PackagePath $DOTNET_CU_PATH -ErrorAction stop | Out-Null
# Dismount
Dismount-WindowsImage -Path $MAIN_OS_MOUNT -Save -ErrorAction stop | Out-Null
# Export
Write-Output "$(Get-TS): Exporting image to $WORKING_PATH\install2.wim"
Export-WindowsImage -SourceImagePath $MEDIA_NEW_PATH"\sources\install.wim" -SourceIndex $IMAGE.ImageIndex -DestinationImagePath $WORKING_PATH"\install2.wim" -ErrorAction stop | Out-Null
}
Move-Item -Path $WORKING_PATH"\install2.wim" -Destination $MEDIA_NEW_PATH"\sources\install.wim" -Force -ErrorAction stop | Out-Null
Обновление WinPE
Этот скрипт аналогичен тому, который обновляет WinRE, но вместо этого он подключает Boot.wim, применяет пакеты с последним накопительным обновлением и сохраняет. Он повторяет это для всех образов внутри Boot.wim, обычно двух образов. Он начинается с применения динамического обновления стека обслуживания. Так как скрипт настраивает этот носитель на японском языке, он устанавливает языковой пакет из папки WinPE в ISO-файле языкового пакета. Кроме того, он добавляет поддержку шрифтов и текста в речь (TTS). Так как скрипт добавляет новый язык, он перестраивает lang.ini, используемый для идентификации языков, установленных в образе. Для второго образа мы сохраняем setup.exe и setuphost.exe для последующего использования, чтобы убедиться, что эти версии соответствуют \sources\setup.exe и \sources\setuphost.exe версии с установочного носителя. Если эти двоичные файлы не идентичны, программа установки Windows завершится ошибкой во время установки. Мы также сохраним обслуживаемые файлы диспетчера загрузки для последующего использования в скрипте. Наконец, скрипт очищает и экспортирует Boot.wim и копирует его обратно на новый носитель.
#
# update Windows Preinstallation Environment (WinPE)
#
# Get the list of images contained within WinPE
$WINPE_IMAGES = Get-WindowsImage -ImagePath $MEDIA_NEW_PATH"\sources\boot.wim"
Foreach ($IMAGE in $WINPE_IMAGES)
{
# update WinPE
Write-Output "$(Get-TS): Mounting WinPE, image index $($IMAGE.ImageIndex)"
Mount-WindowsImage -ImagePath $MEDIA_NEW_PATH"\sources\boot.wim" -Index $IMAGE.ImageIndex -Path $WINPE_MOUNT -ErrorAction stop | Out-Null
# Add servicing stack update (Step 9 from the table)
try
{
Write-Output "$(Get-TS): Adding package $LCU_PATH to WinPE, image index $($IMAGE.ImageIndex)"
Add-WindowsPackage -Path $WINPE_MOUNT -PackagePath $LCU_PATH | Out-Null
}
Catch
{
$theError = $_
Write-Output "$(Get-TS): $theError"
if ($theError.Exception -like "*0x8007007e*")
{
Write-Warning "$(Get-TS): Failed with error 0x8007007e. This failure is a known issue with combined cumulative update, we can ignore."
}
else
{
throw
}
}
# Install lp.cab cab
Write-Output "$(Get-TS): Adding package $WINPE_OC_LP_PATH to WinPE, image index $($IMAGE.ImageIndex)"
Add-WindowsPackage -Path $WINPE_MOUNT -PackagePath $WINPE_OC_LP_PATH -ErrorAction stop | Out-Null
# Install language cabs for each optional package installed
$WINPE_INSTALLED_OC = Get-WindowsPackage -Path $WINPE_MOUNT
Foreach ($PACKAGE in $WINPE_INSTALLED_OC)
{
if ( ($PACKAGE.PackageState -eq "Installed") -and ($PACKAGE.PackageName.startsWith("WinPE-")) -and ($PACKAGE.ReleaseType -eq "FeaturePack") )
{
$INDEX = $PACKAGE.PackageName.IndexOf("-Package")
if ($INDEX -ge 0)
{
$OC_CAB = $PACKAGE.PackageName.Substring(0, $INDEX) + "_" + $LANG + ".cab"
if ($WINPE_OC_LANG_CABS.Contains($OC_CAB))
{
$OC_CAB_PATH = Join-Path $WINPE_OC_LANG_PATH $OC_CAB
Write-Output "$(Get-TS): Adding package $OC_CAB_PATH to WinPE, image index $($IMAGE.ImageIndex)"
Add-WindowsPackage -Path $WINPE_MOUNT -PackagePath $OC_CAB_PATH -ErrorAction stop | Out-Null
}
}
}
}
# Add font support for the new language
if ( (Test-Path -Path $WINPE_FONT_SUPPORT_PATH) )
{
Write-Output "$(Get-TS): Adding package $WINPE_FONT_SUPPORT_PATH to WinPE, image index $($IMAGE.ImageIndex)"
Add-WindowsPackage -Path $WINPE_MOUNT -PackagePath $WINPE_FONT_SUPPORT_PATH -ErrorAction stop | Out-Null
}
# Add TTS support for the new language
if (Test-Path -Path $WINPE_SPEECH_TTS_PATH)
{
if ( (Test-Path -Path $WINPE_SPEECH_TTS_LANG_PATH) )
{
Write-Output "$(Get-TS): Adding package $WINPE_SPEECH_TTS_PATH to WinPE, image index $($IMAGE.ImageIndex)"
Add-WindowsPackage -Path $WINPE_MOUNT -PackagePath $WINPE_SPEECH_TTS_PATH -ErrorAction stop | Out-Null
Write-Output "$(Get-TS): Adding package $WINPE_SPEECH_TTS_LANG_PATH to WinPE, image index $($IMAGE.ImageIndex)"
Add-WindowsPackage -Path $WINPE_MOUNT -PackagePath $WINPE_SPEECH_TTS_LANG_PATH -ErrorAction stop | Out-Null
}
}
# Generates a new Lang.ini file which is used to define the language packs inside the image
if ( (Test-Path -Path $WINPE_MOUNT"\sources\lang.ini") )
{
Write-Output "$(Get-TS): Updating lang.ini"
DISM /image:$WINPE_MOUNT /Gen-LangINI /distribution:$WINPE_MOUNT | Out-Null
if ($LastExitCode -ne 0)
{
throw "Error: Failed to update lang.ini. Exit code: $LastExitCode"
}
}
# Add latest cumulative update
Write-Output "$(Get-TS): Adding package $LCU_PATH to WinPE, image index $($IMAGE.ImageIndex)"
Add-WindowsPackage -Path $WINPE_MOUNT -PackagePath $LCU_PATH -ErrorAction stop | Out-Null
# Perform image cleanup
Write-Output "$(Get-TS): Performing image cleanup on WinPE, image index $($IMAGE.ImageIndex)"
DISM /image:$WINPE_MOUNT /cleanup-image /StartComponentCleanup /ResetBase /Defer | Out-Null
if ($LastExitCode -ne 0)
{
throw "Error: Failed to perform image cleanup on WinPE, image index $($IMAGE.ImageIndex). Exit code: $LastExitCode"
}
if ($IMAGE.ImageIndex -eq "2")
{
# Save setup.exe for later use. This will address possible binary mismatch with the version in the main OS \sources folder
Copy-Item -Path $WINPE_MOUNT"\sources\setup.exe" -Destination $WORKING_PATH"\setup.exe" -Force -ErrorAction stop | Out-Null
# Save setuphost.exe for later use. This will address possible binary mismatch with the version in the main OS \sources folder
# This is only required starting with Windows 11 version 24H2
$TEMP = Get-WindowsImage -ImagePath $MEDIA_NEW_PATH"\sources\boot.wim" -Index $IMAGE.ImageIndex
if ([System.Version]$TEMP.Version -ge [System.Version]"10.0.26100")
{
Copy-Item -Path $WINPE_MOUNT"\sources\setuphost.exe" -Destination $WORKING_PATH"\setuphost.exe" -Force -ErrorAction stop | Out-Null
}
else
{
Write-Output "$(Get-TS): Skipping copy of setuphost.exe; image version $($TEMP.Version)"
}
# Save serviced boot manager files later copy to the root media.
Copy-Item -Path $WINPE_MOUNT"\Windows\boot\efi\bootmgfw.efi" -Destination $WORKING_PATH"\bootmgfw.efi" -Force -ErrorAction stop | Out-Null
Copy-Item -Path $WINPE_MOUNT"\Windows\boot\efi\bootmgr.efi" -Destination $WORKING_PATH"\bootmgr.efi" -Force -ErrorAction stop | Out-Null
}
# Dismount
Dismount-WindowsImage -Path $WINPE_MOUNT -Save -ErrorAction stop | Out-Null
#Export WinPE
Write-Output "$(Get-TS): Exporting image to $WORKING_PATH\boot2.wim"
Export-WindowsImage -SourceImagePath $MEDIA_NEW_PATH"\sources\boot.wim" -SourceIndex $IMAGE.ImageIndex -DestinationImagePath $WORKING_PATH"\boot2.wim" -ErrorAction stop | Out-Null
}
Move-Item -Path $WORKING_PATH"\boot2.wim" -Destination $MEDIA_NEW_PATH"\sources\boot.wim" -Force -ErrorAction stop | Out-Null
Обновление оставшихся файлов мультимедиа
Эта часть скрипта обновляет файлы установки. Он просто копирует отдельные файлы из пакета динамического обновления установки на новый носитель. На этом шаге по мере необходимости будут добавлены обновленные файлы установки, а также последняя база данных совместимости и манифесты компонентов замены. Этот скрипт также выполняет окончательную замену файлов setup.exe, setuphost.exe и диспетчера загрузки с использованием ранее сохраненных версий из WinPE.
#
# update remaining files on media
#
# Add Setup DU by copy the files from the package into the newMedia
Write-Output "$(Get-TS): Adding package $SETUP_DU_PATH"
cmd.exe /c $env:SystemRoot\System32\expand.exe $SETUP_DU_PATH -F:* $MEDIA_NEW_PATH"\sources" | Out-Null
if ($LastExitCode -ne 0)
{
throw "Error: Failed to expand $SETUP_DU_PATH. Exit code: $LastExitCode"
}
# Copy setup.exe from boot.wim, saved earlier.
Write-Output "$(Get-TS): Copying $WORKING_PATH\setup.exe to $MEDIA_NEW_PATH\sources\setup.exe"
Copy-Item -Path $WORKING_PATH"\setup.exe" -Destination $MEDIA_NEW_PATH"\sources\setup.exe" -Force -ErrorAction stop | Out-Null
# Copy setuphost.exe from boot.wim, saved earlier.
if (Test-Path -Path $WORKING_PATH"\setuphost.exe")
{
Write-Output "$(Get-TS): Copying $WORKING_PATH\setuphost.exe to $MEDIA_NEW_PATH\sources\setuphost.exe"
Copy-Item -Path $WORKING_PATH"\setuphost.exe" -Destination $MEDIA_NEW_PATH"\sources\setuphost.exe" -Force -ErrorAction stop | Out-Null
}
# Copy bootmgr files from boot.wim, saved earlier.
$MEDIA_NEW_FILES = Get-ChildItem $MEDIA_NEW_PATH -Force -Recurse -Filter b*.efi
Foreach ($File in $MEDIA_NEW_FILES)
{
if (($File.Name -ieq "bootmgfw.efi") -or ($File.Name -ieq "bootx64.efi") -or ($File.Name -ieq "bootia32.efi") -or ($File.Name -ieq "bootaa64.efi"))
{
Write-Output "$(Get-TS): Copying $WORKING_PATH\bootmgfw.efi to $($File.FullName)"
Copy-Item -Path $WORKING_PATH"\bootmgfw.efi" -Destination $File.FullName -Force -ErrorAction stop | Out-Null
}
elseif ($File.Name -ieq "bootmgr.efi")
{
Write-Output "$(Get-TS): Copying $WORKING_PATH\bootmgr.efi to $($File.FullName)"
Copy-Item -Path $WORKING_PATH"\bootmgr.efi" -Destination $File.FullName -Force -ErrorAction stop | Out-Null
}
}
Завершить
В качестве последнего шага скрипт удаляет рабочую папку временных файлов и отключает наш языковой пакет и компоненты по запросу ISOS.
#
# Perform final cleanup
#
# Remove our working folder
Remove-Item -Path $WORKING_PATH -Recurse -Force -ErrorAction stop | Out-Null
# Dismount ISO images
Write-Output "$(Get-TS): Dismounting ISO images"
Dismount-DiskImage -ImagePath $FOD_ISO_PATH -ErrorAction stop | Out-Null
Write-Output "$(Get-TS): Media refresh completed!"