Search code examples
powershellpowershell-4.0

How to convert array of hash tables to array of strings


How can I convert an array of hash tables to an array of strings?

I'm trying to create a simple menu which will allow a user to select a server from a list. Here's a sample of the list:

$sqlServers = @(
    @{
        key="LOCALDB";
        serverName="(localdb)\mssqllocaldb"; 
        credentials="-E";
        userEntry="L"; 
        menuText="(L)ocaldb`t`t((localdb)\mssqllocaldb)"
    },
    @{
        key="DEV";
        serverName="DEV_SERVER"; 
        credentials="-E";
        userEntry="D"; 
        menuText="(D)ev`t`t`t(DEV_SERVER)"
    },
    @{
        key="TEST";
        serverName="TEST_SERVER"; 
        credentials="-E";
        userEntry="T"; 
        menuText="(T)est`t`t`t(TEST_SERVER)"
    }
)

This will be displayed like:

(L)ocaldb       ((localdb)\mssqllocaldb) 
(D)ev           (DEV_SERVER)
(T)est          (TEST_SERVER)

I want to read the list of valid user choices from my list of servers, then check the key the user has pressed is in that list of valid choices. This is what I've got so far:

function Get-UserSelection (
    [Parameter(Mandatory=$True)]
    $servers
    )
{
    Write-Host "Select the server to run the SQL scripts on (type a letter followed by the [Enter] key, or press CTRL+C to exit)"

    foreach ($server in $servers)
    {
        Write-Host "`t" $server.menuText
    }

    $validSelections = $servers | Select-Object {$_.userEntry}
    $userSelection = ""

    while ($True)
    {
        $userSelection = Read-Host         

        ForEach ($validSelection in $validSelections)
        {
            if ($userSelection -eq $validSelection) 
            {
                return $userSelection
            }
        }
                
        Write-Host "Invalid selection.  Please try again or press CTRL+C to exit"
    }
}

The problem is that the $validSelection, instead of having a value of L or D, has a value like @{$_.userEntry=L} when casting to a string, so the $userSelection (eg "d") is never seen as valid.

I assume the problem is in the line:

$validSelections = $servers | Select-Object {$_.userEntry}

How can I modify this so that $validSelections is an array of strings instead of an array of custom objects?


Solution

  • You are almost there. Just use the ForEach-Object cmdlet to iterate over each hashtable and select the value of userEntry:

    $validSelections = $sqlServers | ForEach-Object {$_.userEntry}