Atualizar a mídia de instalação do Windows com a Atualização Dinâmica

Este artigo explica como adquirir e aplicar pacotes de Atualização Dinâmica a imagens existentes do Windows antes da implantação e inclui Windows PowerShell scripts que você pode usar para automatizar esse processo.

A mídia licenciada por volume está disponível para cada versão do Windows no VLSC (Centro de Serviço de Licenciamento de Volume) e outros canais relevantes, como Windows Update for Business, Windows Server Update Services (WSUS) e Assinaturas do Visual Studio. Você pode usar o Dynamic Update para garantir que os dispositivos Windows tenham os pacotes de atualização de recursos mais recentes como parte de uma atualização in-loco, preservando o pacote de idiomas e recursos sob demanda (FODs) que podem ter sido instalados anteriormente. A Atualização Dinâmica também elimina a necessidade de instalar uma atualização de qualidade separada como parte do processo de atualização local.

Atualização Dinâmica

Sempre que a instalação de uma atualização de recurso é iniciada (seja de mídia ou de um ambiente conectado a Windows Update), a Atualização Dinâmica é uma das primeiras etapas. O Windows Setup entra em contato com um ponto de extremidade da Microsoft para buscar pacotes de Atualização Dinâmica e, em seguida, aplica essas atualizações à mídia de instalação do sistema operacional. Os pacotes de atualização incluem os seguintes tipos de atualizações:

  • Atualizações para Setup.exe binários ou outros arquivos que a Instalação usa para atualizações de recursos
  • Atualizações para o "sistema operacional seguro" (SafeOS) usado para o ambiente de recuperação do Windows
  • Atualizações à pilha de manutenção necessária para concluir a atualização do recurso Para obter mais informações, consulte Atualizações de pilha de manutenção.
  • A atualização cumulativa mais recente (qualidade)
  • Atualizações aos drivers aplicáveis já publicados pelos fabricantes especificamente destinados à Atualização Dinâmica

A Atualização Dinâmica preserva o pacote de idiomas e os pacotes Recursos sob Demanda, solicitando-os novamente.

Os dispositivos devem ser capazes de se conectar à Internet para obter Atualizações Dinâmico. Em alguns ambientes, não é uma opção obter Atualizações Dinâmico. Você ainda pode fazer uma atualização de recurso baseada em mídia adquirindo pacotes de Atualização Dinâmica e aplicando-a à imagem antes de iniciar a Instalação no dispositivo.

Adquirir pacotes de Atualização Dinâmica

Você pode obter pacotes de Atualização Dinâmica do Catálogo de Atualizações da Microsoft. Nesse site, use a barra de pesquisa no canto superior direito para encontrar os pacotes de Atualização Dinâmica para uma versão específica. Os vários pacotes de Atualização Dinâmica podem não estar todos presentes nos resultados de uma única pesquisa, portanto, talvez você precise pesquisar com palavras-chave diferentes para encontrar todas as atualizações. Verifique várias partes dos resultados para ter certeza de que você identificou os arquivos necessários. As tabelas a seguir mostram os principais valores a serem pesquisados ou procurados nos resultados.

Windows 11, versão 22H2 Pacotes de Atualização Dinâmica

O título pode distinguir cada Pacote Dinâmico. As atualizações cumulativas têm a pilha de manutenção inserida. A pilha de manutenção é publicada somente se necessário para uma determinada atualização cumulativa.

Atualizar pacotes Title
Atualização dinâmica do sistema operacional seguro Atualização dinâmica do sistema operacional seguro YYYYY-MM para Windows 11 versão 22H2
Atualização dinâmica de configuração Atualização dinâmica de instalação do YYYYY-MM para Windows 11 versão 22H2
Atualização cumulativa mais recente Atualização cumulativa YYYYY-MM para Windows 11 versão 22H2
Atualização dinâmica da pilha de manutenção Atualização de pilha de manutenção YYYYY-MM para Windows 11 versão 22H2

Windows 11, versão 21H2 Pacotes de Atualização Dinâmica

Título, Produto e Descrição são necessários para distinguir cada Pacote Dinâmico. A atualização cumulativa mais recente tem a pilha de manutenção inserida. Pilha de manutenção publicada separadamente somente se necessário como um pré-requisito para uma determinada atualização cumulativa.

Atualizar pacotes Title Produto Descrição
Atualização dinâmica do sistema operacional seguro Atualização dinâmica YYYYY-MM para Windows 11 Atualização Dinâmica do Sistema Operacional Seguro do Windows ComponentUpdate
Atualização dinâmica de configuração Atualização dinâmica YYYYY-MM para Windows 11 Windows 10 e posterior atualização dinâmica SetupUpdate
Atualização cumulativa mais recente Atualização cumulativa YYYYY-MM para Windows 11
Atualização dinâmica da pilha de manutenção Atualização de pilha de manutenção YYYYY-MM para Windows 11 versão 21H2

Para Windows 10, pacotes de atualização dinâmica versão 22H2

Título, Produto e Descrição são necessários para distinguir cada Pacote Dinâmico. A atualização cumulativa mais recente tem a pilha de manutenção inserida. Pilha de manutenção publicada separadamente somente se necessário como um pré-requisito para uma determinada atualização cumulativa.

Atualizar pacotes Title Produto Descrição
Atualização dinâmica do sistema operacional seguro Atualização dinâmica YYYYY-MM para Windows 10 versão 22H2 Atualização Dinâmica do Sistema Operacional Seguro do Windows ComponentUpdate
Atualização dinâmica de configuração Atualização dinâmica YYYYY-MM para Windows 10 versão 22H2 Windows 10 e posterior atualização dinâmica SetupUpdate
Atualização cumulativa mais recente Atualização cumulativa YYYYY-MM para Windows 10 versão 22H2
Atualização dinâmica da pilha de manutenção Atualização de pilha de manutenção YYYYY-MM para Windows 10 versão 22H2

Se você quiser personalizar a imagem com idiomas adicionais ou Recursos sob Demanda, baixe arquivos ISO de mídia suplementar do Centro de Serviço de Licenciamento de Volume. Por exemplo, se a Atualização Dinâmica for desabilitada para seus dispositivos e se os usuários exigirem recursos específicos sob demanda, você poderá pré-instalá-los na imagem.

Atualizar a mídia de instalação do Windows

Atualizar corretamente a mídia de instalação envolve um grande número de ações operando em vários destinos diferentes (arquivos de imagem). Algumas ações são repetidas em destinos diferentes. Os arquivos de imagens de destino incluem:

  • Ambiente de Pré-instalação do Windows (WinPE): um pequeno sistema operacional usado para instalar, implantar e reparar sistemas operacionais Windows
  • Ambiente de Recuperação do Windows (WinRE): repara causas comuns de sistemas operacionais inexebíveis. O WinRE é baseado no WinPE e pode ser personalizado com drivers adicionais, idiomas, pacotes opcionais e outras ferramentas de solução de problemas ou diagnóstico.
  • Sistema operacional Windows: uma ou mais edições do Windows armazenadas em \sources\install.wim
  • Mídia de instalação do Windows: a coleção completa de arquivos e pastas na mídia de instalação do Windows. Por exemplo, a pasta \sources, \boot folder, Setup.exe e assim por diante.

Esta tabela mostra a sequência correta para aplicar as várias tarefas aos arquivos. Por exemplo, a sequência completa começa com a adição da atualização de pilha de manutenção ao WinRE (1) e termina com a adição do gerenciador de inicialização do WinPE à nova mídia (28).

Tarefa WinRE (winre.wim) Sistema operacional (install.wim) WinPE (boot.wim) Nova mídia
Adicionar atualização dinâmica da pilha de manutenção 1 9 17
Adicionar pacote de idiomas 2 10 18
Adicionar pacotes opcionais localizados 3 19
Adicionar suporte à fonte 4 20
Adicionar texto em fala 5 21
Atualizar Lang.ini 22
Adicionar recursos sob demanda 11
Adicionar atualização dinâmica do sistema operacional seguro 6
Adicionar atualização dinâmica de instalação 26
Adicionar setup.exe do WinPE 27
Adicionar gerenciador de inicialização do WinPE 28
Adicionar atualização cumulativa mais recente 12 23
Limpar a imagem 7 13 24
Adicionar componentes opcionais 14
Adicionar atualizações cumulativas do .NET e do .NET 15
Exportar imagem 8 16 25

Observação

A partir de fevereiro de 2021, a atualização cumulativa mais recente e a atualização de pilha de manutenção serão combinadas e distribuídas no Catálogo de Atualizações da Microsoft como uma nova atualização cumulativa combinada. Para as etapas 1, 9 e 18 que exigem a atualização da pilha de manutenção para atualizar a mídia de instalação, você deve usar a atualização cumulativa combinada. Para obter mais informações sobre a atualização cumulativa combinada, consulte Atualizações de pilha de manutenção.

Observação

A Microsoft removerá o componente Flash do Windows por meio do KB4577586: "Atualização para Remoção do Adobe Flash Player". Você também pode remover o Flash a qualquer momento implantando a atualização em KB4577586 (disponível no Catálogo) entre as etapas 20 e 21. A partir de julho de 2021, KB4577586, "Update for Removal of Adobe Flash Player" será incluído na última atualização cumulativa para Windows 10, versões 1607 e 1507. A atualização também será incluída no Rollup Mensal e na Atualização Somente segurança para Windows 8.1, Windows Server 2012 e Windows Embedded 8 Standard. Para obter mais informações, confira Atualizar no Adobe Flash Player End of Support.

Várias edições do Windows

O main arquivo do sistema operacional (install.wim) pode conter várias edições do Windows. É possível que apenas uma atualização de uma determinada edição seja necessária para implantá-la, com base no índice. Ou pode ser que todas as edições precisem de uma atualização. Além disso, verifique se os idiomas estão instalados antes dos recursos sob demanda e a atualização cumulativa mais recente sempre é aplicada por último.

Idiomas e recursos adicionais

Você não precisa adicionar mais idiomas e recursos à imagem para realizar as atualizações, mas é uma oportunidade de personalizar a imagem com mais idiomas, componentes opcionais e recursos sob demanda além do que está em sua imagem inicial. Quando você adiciona mais idiomas e recursos, é importante fazer essas alterações na ordem correta: primeiro aplique atualizações de pilha de manutenção, seguidas por adições de idioma, depois por adições de recursos e, por fim, a atualização cumulativa mais recente. O script de exemplo fornecido instala um segundo idioma (nesse caso, japonês (ja-JP)). Como esse idioma é apoiado por um lp.cab, não há necessidade de adicionar um Pacote de Experiência de Linguagem. O japonês é adicionado ao sistema operacional main e ao ambiente de recuperação para permitir que o usuário veja as telas de recuperação em japonês. Isso inclui a adição de versões localizadas dos pacotes atualmente instalados na imagem de recuperação.

Componentes opcionais, juntamente com o recurso .NET, podem ser instalados offline, no entanto, isso cria operações pendentes que exigem que o dispositivo seja reiniciado. Como resultado, a chamada para executar a limpeza de imagens falharia. Há duas opções para evitar a falha de limpeza. Uma opção é ignorar a etapa de limpeza de imagens, embora isso resulte em uma instalação.wim maior. Outra opção é instalar os componentes .NET e Opcional em uma etapa após a limpeza, mas antes de exportar. Essa é a opção no script de exemplo. Ao fazer isso, você terá que começar com o install.wim original (sem ações pendentes) ao manter ou atualizar a imagem na próxima vez (por exemplo, no próximo mês).

Windows PowerShell scripts para aplicar o Atualizações Dinâmico a uma imagem existente

Esses exemplos são apenas para ilustração e, portanto, não têm tratamento de erros. O script pressupõe que os seguintes pacotes sejam armazenados localmente nesta estrutura de pastas:

Pasta Descrição
C:\mediaRefresh Pasta pai que contém o script do PowerShell
C:\mediaRefresh\oldMedia Pasta que contém a mídia original que será atualizada. Por exemplo, contém Setup.exe e a pasta \sources.
C:\mediaRefresh\newMedia Pasta que conterá a mídia atualizada. Ele é copiado de \oldMedia e usado como destino para todas as operações de atualização e limpeza.

Introdução

O script começa declarando variáveis globais e criando pastas a serem usadas para montar imagens. Em seguida, faça uma cópia da mídia original, de \oldMedia para \newMedia, mantendo a mídia original no caso de haver um erro de script e é necessário recomeçar de um estado conhecido. Além disso, ele fornece uma comparação de mídia antiga versus nova para avaliar as alterações. Para garantir que as novas atualizações de mídia sejam atualizadas, verifique se elas não são somente leitura.

#Requires -RunAsAdministrator

function Get-TS { return "{0:HH:mm:ss}" -f [DateTime]::Now }

Write-Output "$(Get-TS): Starting media refresh"

# Declare language for showcasing adding optional localized components
$LANG  = "ja-jp"
$LANG_FONT_CAPABILITY = "jpan"

# Declare media for FOD and LPs
# Note: Starting with Windows 11, version 21H2, the language pack (LANGPACK) ISO has been superseded by the FOD ISO.
# Language packs and the \Windows Preinstallation Environment packages are part of the LOF ISO.
# If you are using this script for Windows 10, modify to mount and use the LANGPACK ISO.
$FOD_ISO_PATH    = "C:\mediaRefresh\packages\FOD-PACKAGES_OEM_PT1_amd64fre_MULTI.iso"

# Declare Dynamic Update packages
$LCU_PATH        = "C:\mediaRefresh\packages\LCU.msu"
$SSU_PATH        = "C:\mediaRefresh\packages\SSU_DU.msu"
$SETUP_DU_PATH   = "C:\mediaRefresh\packages\Setup_DU.cab"
$SAFE_OS_DU_PATH = "C:\mediaRefresh\packages\SafeOS_DU.cab"
$DOTNET_CU_PATH  = "C:\mediaRefresh\packages\DotNet_CU.msu"

# Declare folders for mounted images and temp files
$MEDIA_OLD_PATH  = "C:\mediaRefresh\oldMedia"
$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"

# 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

# Note: Starting with Windows 11, version 21H2, the correct path for main OS language and optional features
# moved to \LanguagesAndOptionalFeatures instead of the root. For Windows 10, use $FOD_PATH = $FOD_ISO_DRIVE_LETTER + ":\"
$FOD_PATH = $FOD_ISO_DRIVE_LETTER + ":\LanguagesAndOptionalFeatures"

# 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"

# 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 }

Atualizar o WinRE e cada main edição do Windows do sistema operacional

O script atualizará cada edição do Windows no arquivo do sistema operacional main (install.wim). Para cada edição, a imagem do sistema operacional main é montada.

Para a primeira imagem, Winre.wim é copiado para a pasta de trabalho e montado. Em seguida, aplica a manutenção da atualização dinâmica da pilha, uma vez que seus componentes são usados para atualizar outros componentes. Como o script está opcionalmente adicionando japonês, ele adiciona o pacote de idiomas à imagem e instala as versões japonesas de todos os pacotes opcionais já instalados no Winre.wim. Em seguida, ele aplica o pacote atualização dinâmica do sistema operacional seguro. Ele termina limpando e exportando a imagem para reduzir o tamanho da imagem.

Em seguida, para a imagem do sistema operacional montada, o script começa aplicando a pilha de manutenção Atualização Dinâmica. Em seguida, ele adiciona suporte ao idioma japonês e, em seguida, os recursos de idioma japonês. Ao contrário dos pacotes de Atualização Dinâmica, ele usa Add-WindowsCapability para adicionar esses recursos. Para obter uma lista completa desses recursos e seu nome de funcionalidade associado, consulte Recursos disponíveis sob demanda. Agora é a hora de habilitar outros Componentes Opcionais ou adicionar outros recursos sob demanda. Se esse recurso tiver uma atualização cumulativa associada (por exemplo, .NET), este será o momento de aplicá-los. Em seguida, o script continua com a aplicação da atualização cumulativa mais recente. Por fim, o script limpa e exporta a imagem. Você pode instalar componentes opcionais, juntamente com o recurso .NET, offline, mas isso requer que o dispositivo seja reiniciado. É por isso que o script instala .NET e Componentes Opcionais após a limpeza e antes da exportação.

Esse processo é repetido para cada edição do Windows no arquivo do sistema operacional main. Para reduzir o tamanho, o arquivo Winre.wim atendido da primeira imagem é salvo e usado para atualizar cada edição subsequente do Windows. Isso reduz o tamanho final de install.wim.

#
# Update each main OS Windows image including the Windows Recovery Environment (WinRE)
#

# Get the list of images contained within WinPE
$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)

        # Depending on the Windows release that you are updating, there are 2 different approaches for updating the servicing stack
        # The first approach is to use the combined cumulative update. This is for Windows releases that are shipping a combined 
        # cumulative update that includes the servicing stack updates (i.e. SSU + LCU are combined). Windows 11, version 21H2 and 
        # Windows 11, version 22H2 are examples. In these cases, the servicing stack update is not published seperately; the combined 
        # cumulative update should be used for this step. However, in hopefully rare cases, there may breaking change in the combined 
        # cumulative update format, that requires a standalone servicing stack update to be published, and installed first before the 
        # combined cumulative update can be installed. 

        # This is the code to handle the rare case that the SSU is published and required for the combined cumulative update
        # Write-Output "$(Get-TS): Adding package $SSU_PATH"
        # Add-WindowsPackage -Path $WINRE_MOUNT -PackagePath $SSU_PATH | Out-Null  

        # Now, attempt the combined cumulative update.
        # There is a known issue where the servicing stack update is installed, but the cumulative update will fail. This error should 
        # be caught and ignored, as the last step will be to apply the Safe OS update and thus the image will be left with the correct 
        # packages installed.

        try
        {
            Add-WindowsPackage -Path $WINRE_MOUNT -PackagePath $LCU_PATH | Out-Null  
        }
        Catch
        {
            $theError = $_
            Write-Output "$(Get-TS): $theError"
    
            if ($theError.Exception -like "*0x8007007e*") {
                Write-Output "$(Get-TS): This failure is a known issue with combined cumulative update, we can ignore."
            }
            else {
                throw
            }
        }

        # The second approach for Step 1 is for Windows releases that have not adopted the combined cumulative update
        # but instead continue to have a seperate servicing stack update published. In this case, we'll install the SSU
        # update. This second approach is commented out below.

        # Write-Output "$(Get-TS): Adding package $SSU_PATH"
        # Add-WindowsPackage -Path $WINRE_MOUNT -PackagePath $SSU_PATH | Out-Null  

        #
        # Optional: Add the language to recovery environment
        #
        # Install lp.cab cab
        Write-Output "$(Get-TS): Adding package $WINPE_OC_LP_PATH"
        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"
                        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"
            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"
                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"
                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"
        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

        # 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 18 from the table)

    # Depending on the Windows release that you are updating, there are 2 different approaches for updating the servicing stack
    # The first approach is to use the combined cumulative update. This is for Windows releases that are shipping a combined cumulative update that
    # includes the servicing stack updates (i.e. SSU + LCU are combined). Windows 11, version 21H2 and Windows 11, version 22H2 are examples. In these
    # cases, the servicing stack update is not published seperately; the combined cumulative update should be used for this step. However, in hopefully
    # rare cases, there may breaking change in the combined cumulative update format, that requires a standalone servicing stack update to be published, 
    # and installed first before the combined cumulative update can be installed. 

    # This is the code to handle the rare case that the SSU is published and required for the combined cumulative update
    # Write-Output "$(Get-TS): Adding package $SSU_PATH"
    # Add-WindowsPackage -Path $MAIN_OS_MOUNT -PackagePath $SSU_PATH | Out-Null  

    # Now, attempt the combined cumulative update. Unlike WinRE and WinPE, we don't need to check for error 0x8007007e
    Write-Output "$(Get-TS): Adding package $LCU_PATH"
    Add-WindowsPackage -Path $MAIN_OS_MOUNT -PackagePath $LCU_PATH | Out-Null  

    # The second approach for Step 18 is for Windows releases that have not adopted the combined cumulative update
    # but instead continue to have a seperate servicing stack update published. In this case, we'll install the SSU
    # update. This second approach is commented out below.

    # Write-Output "$(Get-TS): Adding package $SSU_PATH"
    # Add-WindowsPackage -Path $MAIN_OS_MOUNT -PackagePath $SSU_PATH | Out-Null  

    # Optional: Add language to main OS
    Write-Output "$(Get-TS): Adding package $OS_LP_PATH"
    Add-WindowsPackage -Path $MAIN_OS_MOUNT -PackagePath $OS_LP_PATH -ErrorAction stop | Out-Null  

    # Optional: Add a Features on Demand to the image
    Write-Output "$(Get-TS): Adding language FOD: Language.Fonts.Jpan~~~und-JPAN~0.0.1.0"
    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"
    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"
    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"
    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"
    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"
    Add-WindowsCapability -Name "Language.Speech~~~$LANG~0.0.1.0" -Path $MAIN_OS_MOUNT -Source $FOD_PATH -ErrorAction stop | Out-Null

    # Note: If I wanted to enable additional Features on Demand, I'd add these here.

    # Add latest cumulative update
    Write-Output "$(Get-TS): Adding package $LCU_PATH"
    Add-WindowsPackage -Path $MAIN_OS_MOUNT -PackagePath $LCU_PATH -ErrorAction stop | Out-Null

    # Perform image cleanup
    Write-Output "$(Get-TS): Performing image cleanup on main OS"
    DISM /image:$MAIN_OS_MOUNT /cleanup-image /StartComponentCleanup | Out-Null

    #
    # Note: If I wanted to enable additional Optional Components, I'd add these here.
    # In addition, we'll add .NET 3.5 here as well. Both .NET and Optional Components might require
    # the image to be booted, and thus if we tried to cleanup after installation, it would fail.
    #

    Write-Output "$(Get-TS): Adding NetFX3~~~~"
    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"
    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

Atualizar WinPE

Esse script é semelhante ao que atualiza o WinRE, mas, em vez disso, ele monta Boot.wim, aplica os pacotes com a última atualização cumulativa por último e salva. Ele repete isso para todas as imagens dentro de Boot.wim, normalmente duas imagens. Ele começa aplicando a atualização dinâmica da pilha de manutenção. Como o script está personalizando essa mídia com japonês, ele instala o pacote de idiomas da pasta WinPE no ISO do pacote de idiomas. Além disso, ele adiciona suporte de fonte e texto à fala (TTS). Como o script está adicionando um novo idioma, ele recompila lang.ini, usado para identificar idiomas instalados na imagem. Para a segunda imagem, salvaremos setup.exe para uso posterior, para garantir que essa versão corresponda à versão \sources\setup.exe da mídia de instalação. Se esses binários não forem idênticos, a Instalação do Windows falhará durante a instalação. Também salvaremos os arquivos do gerenciador de inicialização atendidos para uso posterior no script. Por fim, o script limpa e exporta Boot.wim e o copia de volta para a nova mídia.

#
# 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)

    # Depending on the Windows release that you are updating, there are 2 different approaches for updating the servicing stack
    # The first approach is to use the combined cumulative update. This is for Windows releases that are shipping a combined 
    # cumulative update that includes the servicing stack updates (i.e. SSU + LCU are combined). Windows 11, version 21H2 and 
    # Windows 11, version 22H2 are examples. In these cases, the servicing stack update is not published separately; the combined 
    # cumulative update should be used for this step. However, in hopefully rare cases, there may breaking change in the combined 
    # cumulative update format, that requires a standalone servicing stack update to be published, and installed first before the 
    # combined cumulative update can be installed. 

    # This is the code to handle the rare case that the SSU is published and required for the combined cumulative update
    # Write-Output "$(Get-TS): Adding package $SSU_PATH"
    # Add-WindowsPackage -Path $WINPE_MOUNT -PackagePath $SSU_PATH | Out-Null  

    # Now, attempt the combined cumulative update.
    # There is a known issue where the servicing stack update is installed, but the cumulative update will fail.
    # This error should be caught and ignored, as the last step will be to apply the cumulative update 
    # (or in this case the combined cumulative update) and thus the image will be left with the correct packages installed.

    try
    {
        Add-WindowsPackage -Path $WINPE_MOUNT -PackagePath $LCU_PATH | Out-Null  
    }
    Catch
    {
        $theError = $_
        Write-Output "$(Get-TS): $theError"

        if ($theError.Exception -like "*0x8007007e*") {
            Write-Output "$(Get-TS): This failure is a known issue with combined cumulative update, we can ignore."
        }
        else {
            throw
        }
    }

    # The second approach for Step 9 is for Windows releases that have not adopted the combined cumulative update
    # but instead continue to have a separate servicing stack update published. In this case, we'll install the SSU
    # update. This second approach is commented out below.

    # Write-Output "$(Get-TS): Adding package $SSU_PATH"
    # Add-WindowsPackage -Path $WINPE_MOUNT -PackagePath $SSU_PATH | Out-Null 

    # Install lp.cab cab
    Write-Output "$(Get-TS): Adding package $WINPE_OC_LP_PATH"
    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"
                    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"
        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"
            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"
            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
    }

    # Add latest cumulative update
    Write-Output "$(Get-TS): Adding package $LCU_PATH"
    Add-WindowsPackage -Path $WINPE_MOUNT -PackagePath $LCU_PATH -ErrorAction stop | Out-Null  

    # Perform image cleanup
    Write-Output "$(Get-TS): Performing image cleanup on WinPE"
    DISM /image:$WINPE_MOUNT /cleanup-image /StartComponentCleanup /ResetBase /Defer | Out-Null

    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 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

Atualizar arquivos de mídia restantes

Essa parte do script atualiza os arquivos de instalação. Ele simplesmente copia os arquivos individuais no pacote de Atualização Dinâmica de Instalação para a nova mídia. Esta etapa traz arquivos de instalação atualizados conforme necessário, juntamente com o banco de dados de compatibilidade mais recente e manifestos de componente de substituição. Esse script também faz uma substituição final de arquivos do gerenciador de inicialização e setup.exe usando as versões salvas anteriormente do 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

# 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 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
    }
}

Concluir

Como última etapa, o script remove a pasta de trabalho de arquivos temporários e desmonta nosso pacote de idiomas e RECURSOS sob Demanda 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!"