private/BootMedia/Select-OSDeployCoreCacheWindowsRE.ps1

#Requires -PSEdition Core

function Select-OSDeployCoreCacheWindowsRE {
    <#
    .SYNOPSIS
        Displays imported WinRE sources in a console picker.
 
    .DESCRIPTION
        Wraps Get-OSDeployCoreCacheWindowsRE and presents the results in a native
        console table for interactive selection with the Up and Down arrow keys.
 
    .PARAMETER Architecture
        Filter by architecture before displaying the picker.
 
    .NOTES
        Author: David Segura
        Version: 0.1.0
 
    Dependencies:
      Module Functions: Get-OSDeployCoreCacheWindowsRE, Write-OSDeployCoreProgress
            .NET Classes: [System.Console]
    #>

    [CmdletBinding()]
    param (
        [ValidateSet('amd64', 'arm64')]
        [System.String]
        $Architecture
    )

    $params = @{}
    if ($Architecture) { $params.Architecture = $Architecture }

    $results = Get-OSDeployCoreCacheWindowsRE @params

    if ($results) {
        if (@($results).Count -eq 1) {
            Write-OSDeployCoreProgress 'Auto-selected the only available Windows Recovery Image'
            return $results
        }

        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] Recovery Images are saved in $env:ProgramData\OSDeployCore\cache\windows-re"

        if ([Console]::IsInputRedirected -or [Console]::IsOutputRedirected) {
            Write-Warning "[$(Get-Date -Format s)] An interactive console is required to select a Windows Recovery Image"
            return
        }

        $resultItems = @($results)
        $displayResults = @($resultItems | Select-Object Name, Architecture, OSVersion, Version, Languages, ImageSize)
        $columnNames = @('Name', 'Architecture', 'OSVersion', 'Version', 'Languages', 'ImageSize')
        $tableRows = for ($resultIndex = 0; $resultIndex -lt $displayResults.Count; $resultIndex++) {
            $displayResult = $displayResults[$resultIndex]
            [PSCustomObject]@{
                Result = $resultItems[$resultIndex]
                Values = @($columnNames | ForEach-Object { [string]$displayResult.$_ })
            }
        }

        $columnWidths = foreach ($columnIndex in 0..($columnNames.Count - 1)) {
            $maximumValueLength = ($tableRows | ForEach-Object { $_.Values[$columnIndex].Length } | Measure-Object -Maximum).Maximum
            [Math]::Max($columnNames[$columnIndex].Length, $maximumValueLength)
        }

        $header = (($columnNames | ForEach-Object -Begin { $columnIndex = 0 } -Process {
                    $value = $_.PadRight($columnWidths[$columnIndex])
                    $columnIndex++
                    $value
                }) -join ' ')

        $selectedIndex = 0
        $consoleTop = [Console]::CursorTop
        do {
            [Console]::SetCursorPosition(0, $consoleTop)
            Write-Host
            Write-Host -ForegroundColor Cyan "Select a Windows Recovery Image (Up/Down to select, Enter to continue, Escape to cancel)"
            Write-Host $header

            for ($rowIndex = 0; $rowIndex -lt $tableRows.Count; $rowIndex++) {
                $tableRow = (($tableRows[$rowIndex].Values | ForEach-Object -Begin { $columnIndex = 0 } -Process {
                                $value = $_.PadRight($columnWidths[$columnIndex])
                                $columnIndex++
                                $value
                            }) -join ' ')

                if ($rowIndex -eq $selectedIndex) {
                    Write-Host "> $tableRow" -ForegroundColor Black -BackgroundColor Cyan
                }
                else {
                    Write-Host " $tableRow"
                }
            }

            $key = [Console]::ReadKey($true).Key
            switch ($key) {
                'UpArrow' { if ($selectedIndex -gt 0) { $selectedIndex-- } }
                'DownArrow' { if ($selectedIndex -lt ($tableRows.Count - 1)) { $selectedIndex++ } }
                'Escape' {
                    [Console]::WriteLine()
                    return
                }
            }
        } until ($key -eq 'Enter')

        [Console]::WriteLine()
        return $tableRows[$selectedIndex].Result
    }
    else {
        Write-Warning "[$(Get-Date -Format s)] [$($MyInvocation.MyCommand.Name)] No WinRE sources available for selection"
        return $null
    }
}