Dstr0
Dstr0

Reputation: 145

File select menu with PowerShell (not dialog box)

I have this script right here:

$directory = "C:\New Folder"
$counter = 1

Set-Location $directory

#Menu
Write-Host "==========" -BackgroundColor DarkGreen
Write-Host "===MENU===" -BackgroundColor DarkGreen
Write-Host "==========" -BackgroundColor DarkGreen
#Shows only .wav files and it order them
Get-ChildItem -Name -Include *.wav | ForEach-Object {Write-Host "[$counter] " -ForegroundColor Green -NoNewLine; Write-Host "$_"; $counter++}
Write-Host ""

$input = Read-Host -Prompt "Select a file from the menu"
Clear-Host
Write-Host "You have just selected: $input"

At this point i would like to display the name of the selected file. How could i do that?

Upvotes: 1

Views: 946

Answers (2)

Abraham Zinala
Abraham Zinala

Reputation: 4694

Although an answer has been accepted, I will demonstrate how you can make a selection out of files using the for loop.

We first have to start by gathering the files using Get-ChildItem like so:

$WavFiles = Get-ChildItem -Filter "*.wav"

Notice how I didn't just narrow it down to JUST names? This gives us more options to work with such as, adding the last write time to our selection menu so we can see when they were last worked on.

Next, we will create a PSCustomObject to store our results and make a listing out of them using a for loop to assigning a number to each file name based off our gathered items in $WavFiles.

$(for($i=0; $i -lt $WavFiles.Count; $i++){
    [PSCustomObject]@{
        'File Name'       = "${i}: $($WavFiles.BaseName[$i])"
        'Last Write Time' = $WavFiles.LastWriteTime[$i]
            }
        }) | Out-Host

If you're familiar on how to make a selection out of an array ( $array[3] ), you should be able to peace together whats happening when we iterate though our collection of $WavFiles simply by assigning it, its corresponding array number. The $() | Out-Host is added due to Read-Host taking precedence and displaying before the output of our object; this is a work around for that which you can read more about it here.

Lastly, we ask for user input with our Read-Host assigning the input value to $input which we will use to once again, reference the corresponding file using the number its assigned in our collection of $WavFiles

$input = Read-Host -Prompt "Select a file from the menu" Clear-Host Write-Host "You have just selected: $($WavFiles[$input])"

The $input variable becomes the number selected which is why we can use it to reference the corresponding value in the array.

It all comes together like so:

#$directory = "C:\New Folder"
#Set-Location $directory

$WavFiles = Get-ChildItem -Filter "*.wav"
    
    $(for($i=0; $i -lt $WavFiles.Count; $i++){
        [PSCustomObject]@{
            'File Name'       = "${i}: $($WavFiles.BaseName[$i])"
            'Last Write Time' = $WavFiles.LastWriteTime[$i]
                }
            }) | Out-Host

$input = Read-Host -Prompt "Select a file from the menu"
Clear-Host
Write-Host "You have just selected: $($WavFiles[$input])"

Output:


File Name                 Last Write Time      
---------                 ---------------      
0: Eula                   3/2/2011 9:48:57 AM  
1: psversion              3/2/2011 9:48:56 AM  
2: readme                 11/6/2020 12:57:53 PM
3: ThirdPartyNoticesBySHS 2/27/2021 10:31:01 PM
4: WindowsCodecsRaw       3/18/2019 10:46:13 PM

Upvotes: 4

Rich Moss
Rich Moss

Reputation: 2384

I created function for this purpose that I described here.

It may be overkill for your needs but you can pass the set of *.wav files with this code:

Show-SimpleMenu (get-childitem *.wav).Name

Please feel free to report any issues on GitHub, or here.

Upvotes: 3

Related Questions