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 25H2 or later, 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-IsWindows1125H2)) {
        throw "[$(Get-Date -Format s)] [$($MyInvocation.MyCommand.Name)] Windows 11 25H2 (build 26200) is required."
    }
    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"
    #=================================================
}