private/Disk/Select-OSDeployDiskUSB.ps1

function Select-OSDeployDiskUSB {
    <#
    .SYNOPSIS
        Presents a picker for the user to select a USB disk.
 
    .NOTES
        Author: David Segura
        Company: Recast Software
 
        Dependencies:
            Module Functions: Get-OSDeployDisk
            .NET Classes: [System.Console], [System.Management.Automation.SwitchParameter]
    #>

    [CmdletBinding()]
    param (
        [Parameter(ValueFromPipeline = $true)]
        [Object]$Input,

        [Alias('Min','MinGB','MinSize')]
        [int]$MinimumSizeGB = 8,

        [Alias('Max','MaxGB','MaxSize')]
        [int]$MaximumSizeGB = 1800,

        [System.Management.Automation.SwitchParameter]$Skip,
        [System.Management.Automation.SwitchParameter]$SelectOne
    )
    #=================================================
    # Get-Disk
    #=================================================
    if ($Input) {
        $Results = $Input
    } else {
        $Results = Get-OSDeployDisk -BusType USB | Where-Object {($_.Size -gt ($MinimumSizeGB * 1GB)) -and ($_.Size -lt ($MaximumSizeGB * 1GB))}
    }
    #=================================================
    # Process Results
    #=================================================
    if ($Results) {
        #=================================================
        # There was only 1 Item, then we will select it automatically
        #=================================================
        if ($PSBoundParameters.ContainsKey('SelectOne')) {
            Write-Verbose "[$(Get-Date -Format s)] [$($MyInvocation.MyCommand.Name)] Automatically select "
            if (($Results | Measure-Object).Count -eq 1) {
                $SelectedItem = $Results
                Return $SelectedItem
            }
        }
        #=================================================
        # Select an Item
        #=================================================
        $DisplayResults = @($Results | Select-Object -Property Number, BusType, MediaType,`
        @{Name='SizeGB';Expression={[int]($_.Size / 1GB)}},`
        FriendlyName, Model, PartitionStyle,`
        @{Name='Partitions';Expression={$_.NumberOfPartitions}})

        if ([Console]::IsInputRedirected -or [Console]::IsOutputRedirected) {
            Write-Warning "[$($MyInvocation.MyCommand.Name)] An interactive console is required to select a USB disk"
            return
        }

        $columnNames = @('Number', 'BusType', 'MediaType', 'SizeGB', 'FriendlyName', 'Model', 'PartitionStyle', 'Partitions')
        $tableRows = foreach ($row in $DisplayResults) {
            [PSCustomObject]@{
                Disk   = $row
                Values = @($columnNames | ForEach-Object { [string]$row.$_ })
            }
        }

        $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 DarkGreen 'Select a USB Disk (Up/Down to select, Enter to continue, Escape to cancel)'
            Write-Host -ForegroundColor DarkGray $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()
                    if ($PSBoundParameters.ContainsKey('Skip')) { return $false }
                    return
                }
            }
        } until ($key -eq 'Enter')

        [Console]::WriteLine()
        Return ($Results | Where-Object { $_.Number -eq $tableRows[$selectedIndex].Disk.Number })
        #=================================================
    }
}