public/Update-OSDeployBootISO.ps1

#Requires -PSEdition Core

function Update-OSDeployBootISO {
    <#
    .SYNOPSIS
        Rebuilds bootable ISO files for a selected OSDeploy Core BootImage build
 
    .DESCRIPTION
        Opens an Out-GridView selector for a completed BootImage build, verifies that the
        Windows ADK is installed, and rebuilds bootmedia.iso from its bootmedia directory.
        When the selected build also contains bootmedia_ca2023, rebuilds
        bootmedia_ca2023.iso.
 
        The ISO build temporarily copies saved OSDCloud profiles into the source media and
        removes those copied profiles afterward. It uses the existing media directories and
        does not mount or modify a WIM. -WhatIf still performs prerequisite checks, opens the
        BootImage selector, verifies the ADK, and populates the global BuildMedia state, but
        it does not invoke the ISO build step.
 
    .EXAMPLE
        PS> Update-OSDeployBootISO
 
        Prompts for a completed BootImage build and rebuilds its available ISO files using
        the installed Windows ADK.
 
    .EXAMPLE
        PS> Update-OSDeployBootISO -WhatIf
 
        Prompts for a BootImage build and shows the planned ISO rebuild without invoking the
        ISO build step.
 
    .INPUTS
        None. This function does not accept pipeline input.
 
    .OUTPUTS
        None.
 
    .NOTES
        Author: David Segura
        Company: Recast Software
        Version: 1.0.0
        Date: 2026-08-28
 
        Requires Windows 11. During preview, other releases warn and continue. Windows 11
        26H2 build 26300 will be required for release. Requires PowerShell 7.4 or later installed from MSI,
        curl.exe, Windows ADK, Administrator rights, and a completed BootImage build.
 
        Populates the global BuildMedia variable for the ISO build step.
 
    .LINK
        https://learn.microsoft.com/en-us/windows-hardware/get-started/adk-install
 
    .LINK
        https://github.com/RecastSoftware/RecastOSDeploy
    #>


    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')]
    param ()
    #=================================================
    Write-HostOSDeployBanner
    #=================================================
    # Require License for this function. If the license is not valid, return without executing the function.
    if (-not (Test-OSDeployLicenseGate -CommandName $MyInvocation.MyCommand.Name)) {
        return
    }
    #=================================================
    # Stop before rebuilding media when a required host capability is missing.
    if (-not (Test-IsWindows11)) {
        throw "[$(Get-Date -Format s)] [$($MyInvocation.MyCommand.Name)] Windows 11 is required."
    }
    if (-not (Test-IsWindows1126H2)) {
        Write-Warning "[$($MyInvocation.MyCommand.Name)] OSDeploy requires Windows 11 26H2 and will be enforced in an updated OSDeploy release. Continuing preview execution."
    }
    if (-not (Test-PwshVersionMin)) {
        throw "[$(Get-Date -Format s)] [$($MyInvocation.MyCommand.Name)] PowerShell 7.4 or higher is required."
    }
    if (-not (Test-PwshPSHome)) {
        throw "[$(Get-Date -Format s)] [$($MyInvocation.MyCommand.Name)] The MSI installation of PowerShell 7 is required."
    }
    if (-not (Test-CommandCurl)) {
        throw "[$(Get-Date -Format s)] [$($MyInvocation.MyCommand.Name)] curl.exe is required but was not found in the current PATH. curl.exe ships with Windows 10 1803+."
    }
    if (-not (Test-IsAdministrator)) {
        throw "[$(Get-Date -Format s)] [$($MyInvocation.MyCommand.Name)] Administrator rights are required. Re-run PowerShell as Administrator and try again."
    }
    #=================================================
    Initialize-OSDeployCorePaths
    #=================================================
    # Stop when no completed BootImage is selected.
    # Select a BootImage build
    $SelectBootImage = Select-OSDeployCoreBootMedia
    if ($null -eq $SelectBootImage) {
        Write-Warning "[$(Get-Date -Format s)] No OSDeployCore BootImage build was found or selected"
        return
    }
    Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] [INFO] Selected BootImage: $($SelectBootImage.Name)"
    Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] [INFO] BootImage path: $($SelectBootImage.Path)"
    #=================================================
    # Stop when the ADK tool required to create ISO files is unavailable.
    # Verify Windows ADK is installed
    $AdkInfo = Get-OSDeployWindowsAdkInstall
    if (-not $AdkInfo.IsInstalled) {
        Write-Warning "[$(Get-Date -Format s)] Windows ADK is not installed"
        Write-Warning "[$(Get-Date -Format s)] Install the Windows ADK from https://learn.microsoft.com/en-us/windows-hardware/get-started/adk-install"
        return
    }
    Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] [INFO] Windows ADK $($AdkInfo.InstallVersion)"
    Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] [INFO] Windows ADK: $($AdkInfo.InstallPath)"
    #=================================================
    # Build media paths
    $MediaPath = Join-Path $SelectBootImage.Path 'bootmedia'
    if (-not (Test-Path -Path $MediaPath)) {
        Write-Warning "[$(Get-Date -Format s)] bootmedia directory not found: $MediaPath"
        return
    }

    $MediaPathEX = Join-Path $SelectBootImage.Path 'bootmedia_ca2023'
    # Build the CA 2023 ISO only when its source media exists.
    if (-not (Test-Path -Path $MediaPathEX)) {
        $MediaPathEX = $null
    }
    #=================================================
    # Set BuildMedia global for Step-BuildBootMediaIso
    $global:BuildMedia = [ordered]@{
        AdkRootPath   = $AdkInfo.InstallPath
        MediaIsoLabel = $SelectBootImage.Name
        MediaPath     = $MediaPath
        MediaPathEX   = $MediaPathEX
        MediaRootPath = $SelectBootImage.Path
    }

    Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] [INFO] MediaPath: $MediaPath"
    if ($MediaPathEX) {
        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] [INFO] MediaPathEX: $MediaPathEX"
    }
    Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] [INFO] MediaRootPath: $($SelectBootImage.Path)"
    #=================================================
    # Honor WhatIf and Confirm before replacing ISO output files.
    if ($PSCmdlet.ShouldProcess($SelectBootImage.Path, 'Rebuild BootMedia ISO files')) {
        Step-BuildBootMediaIso
    }
    #=================================================
    Write-Verbose "[$($MyInvocation.MyCommand.Name)] End"
    #=================================================
}