private/Select-OSDeployCoreCacheWindowsRE.ps1

#Requires -PSEdition Core

function Select-OSDeployCoreCacheWindowsRE {
    <#
    .SYNOPSIS
        Selects an imported Windows Recovery Environment image
 
    .DESCRIPTION
        Gets imported Windows Recovery Environment images and returns the only result
        automatically when exactly one is available. Multiple results are displayed in
        a native console table that supports Up and Down arrow navigation, Enter to select,
        and Escape to cancel.
 
        An interactive, nonredirected console is required only when multiple results must
        be displayed. The function writes a warning and returns no object when no matching
        images exist or interactive selection cannot be displayed.
 
    .PARAMETER Architecture
        Limits results to amd64 or arm64 before automatic or interactive selection.
 
    .EXAMPLE
        PS> Select-OSDeployCoreCacheWindowsRE -Architecture amd64
 
        Returns the only imported amd64 image or displays matching images for console selection.
 
    .INPUTS
        None. This function does not accept pipeline input.
 
    .OUTPUTS
        System.Management.Automation.PSCustomObject. Returns the selected Windows RE source,
        or no object when none is selected or available.
 
    .NOTES
        Author: David Segura
        Company: Recast Software
        Version: 0.1.0
        Date: 2026-08-28
 
    .LINK
        Get-OSDeployCoreWindowsRE
    #>

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

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

    $results = Get-OSDeployCoreWindowsRE @params

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

        Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] [INFO] Recovery Images: $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 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)] No WinRE sources available for selection"
        return $null
    }
}