private/BootMedia/Steps/New-WindowsAdkISO.ps1

#Requires -PSEdition Core

function New-WindowsAdkISO {
    <#
    .SYNOPSIS
        Creates a bootable ISO using oscdimg.exe from the Windows ADK.
 
    .DESCRIPTION
        Uses oscdimg.exe to create a UEFI-bootable ISO image from a WinPE media directory.
 
    .PARAMETER MediaPath
        The path to the WinPE media directory containing the boot files.
 
    .PARAMETER IsoFileName
        The filename for the output ISO file (e.g., BootMedia.iso).
 
    .PARAMETER IsoLabel
        The volume label for the ISO.
 
    .PARAMETER WindowsAdkRoot
        The ADK root path used to locate oscdimg.exe and efisys_noprompt.bin.
 
    .PARAMETER IsoDirectory
        The output directory where the ISO file will be created.
 
    .NOTES
        Author: David Segura
        Version: 0.1.0
    #>

    [CmdletBinding(SupportsShouldProcess)]
    param (
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [System.String]
        $MediaPath,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [System.String]
        $IsoFileName,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [System.String]
        $IsoLabel,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [System.String]
        $WindowsAdkRoot,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [System.String]
        $IsoDirectory
    )

    if (-not (Test-Path -Path $MediaPath)) {
        Write-Error "MediaPath not found: $MediaPath"
        return
    }

    # Locate oscdimg.exe - check both amd64 and arm64
    $oscdimgExe = $null
    foreach ($arch in @('amd64', 'arm64')) {
        $candidate = Join-Path $WindowsAdkRoot "Deployment Tools\$arch\Oscdimg\oscdimg.exe"
        if (Test-Path $candidate) {
            $oscdimgExe = $candidate
            break
        }
    }

    if (-not $oscdimgExe) {
        Write-Error "oscdimg.exe not found under $WindowsAdkRoot"
        return
    }

    # Locate efisys_noprompt.bin / efisys.bin: media path first, then ADK Oscdimg directory
    $efisysBin = $null
    $oscdimgDir = Split-Path $oscdimgExe -Parent
    foreach ($candidate in @(
        (Join-Path $MediaPath    'EFI\Microsoft\Boot\efisys_noprompt.bin'),
        (Join-Path $MediaPath    'EFI\Microsoft\Boot\efisys.bin'),
        (Join-Path $oscdimgDir   'efisys_noprompt.bin'),
        (Join-Path $oscdimgDir   'efisys.bin')
    )) {
        if (Test-Path $candidate) {
            $efisysBin = $candidate
            break
        }
    }

    if (-not $efisysBin) {
        Write-Error "efisys.bin not found in $MediaPath or $oscdimgDir"
        return
    }

    $isoFilePath = Join-Path $IsoDirectory $IsoFileName

    if (-not (Test-Path $IsoDirectory)) {
        New-Item -Path $IsoDirectory -ItemType Directory -Force | Out-Null
    }

    if ($PSCmdlet.ShouldProcess($isoFilePath, 'Create bootable ISO')) {
        Write-OSDeployCoreProgress "Creating ISO: $isoFilePath"

        # UEFI-only ISO creation
        $oscdimgArgs = @(
            '-m'
            '-o'
            '-u2'
            '-udfver102'
            "-bootdata:1#pEF,e,b`"$efisysBin`""
            "-l`"$IsoLabel`""
            "`"$MediaPath`""
            "`"$isoFilePath`""
        )

        $process = Start-Process -FilePath $oscdimgExe -ArgumentList $oscdimgArgs -NoNewWindow -Wait -PassThru
        if ($process.ExitCode -ne 0) {
            Write-Error "oscdimg.exe exited with code $($process.ExitCode)"
        }
        else {
            Write-OSDeployCoreProgress "ISO created: $isoFilePath"
            Get-Item $isoFilePath
        }
    }
}