Hash Table keys outputs a single string instead of an array

Viewed 48

Why is the hash table output a single string not a array?


$ServicesList = @{
    "Exhange Online"               = "Connect-ExchangeOnline"
    "Security & Compliance Center" = "Connect-IPPSSession"
    "Azure Active Directory"       = "Connect-AzureAD"
    "Microsoft Online"             = "Connect-MsolService"
    "SharePoint Online"            = "Connect-SPOService -Url $url"
    "Microsoft Teams"              = "Connect-MicrosoftTeams"
    "Microsoft Graph"              = "Connect-Graph"
    "Azure Account"                = "Connect-AzAccount"
}

$ServicesListKeys = $ServicesList.Keys

function Menu {
    $menu = @{}
    for ($i = 1; $i -le $ServicesListKeys.count; $i++) {
        Write-Host "$i. $($ServicesListKeys[$i-1])" 
        $menu.Add($i, ($ServicesListKeys[$i - 1]))
    }
    [int]$ans = Read-Host 'Enter selection'
    $selection = $menu.Item($ans) ; $ServicesList[$selection]
}

Menu

Output:

  1. Azure Active Directory Microsoft Graph Microsoft Online Azure Account Security & Compliance Center Exhange Online Microsoft Teams SharePoint Online

when it workers with a normal array

$array = "Red", "green", "Blue"

Output:

  1. Red
  2. green
  3. Blue
1 Answers

Hashtable only supports Item[Object]:

Gets or sets the value associated with the specified key.

Whereas OrderedDictionary supports both, Item[Object] and Item[Int32], the latter being:

Gets or sets the value at the specified index.

In this case you could simply change your hashtable for an ordered dictionary, not only because it supports getting values by index but also because the key / value pairs will always retain the same order. By using a hashtable, the items on your Menu not always have the same order.

Here is a simplified working version of your code:

$ServicesList = [ordered]@{
    "Exhange Online"               = "Connect-ExchangeOnline"
    "Security & Compliance Center" = "Connect-IPPSSession"
    "Azure Active Directory"       = "Connect-AzureAD"
    "Microsoft Online"             = "Connect-MsolService"
    "SharePoint Online"            = "Connect-SPOService -Url $url"
    "Microsoft Teams"              = "Connect-MicrosoftTeams"
    "Microsoft Graph"              = "Connect-Graph"
    "Azure Account"                = "Connect-AzAccount"
}

function Menu {
    param($Dictionary)

    $i = 1; $ServicesList.PSBase.Keys | ForEach-Object {
        Write-Host "$(($i++)). $_"
    }

    [int] $ans = Read-Host 'Enter selection'

    if($value = $Dictionary[$ans - 1]) {
        return $value
    }
    Write-Warning "Invalid selection!"
}

Menu -Dictionary $ServicesList
Related