Getting the current hash key in a ForEach-Object loop in powershell

42,077

Solution 1

I like to use GetEnumerator() when looping a hashtable. It will give you a property value with the object, and a property key with it's key/name. Try:

$myHash.GetEnumerator() | % { 
    Write-Host "Current hashtable is: $($_.key)"
    Write-Host "Value of Entry 1 is: $($_.value["Entry 1"])" 
}

Solution 2

You can also do this without a variable

@{
  'foo' = 222
  'bar' = 333
  'baz' = 444
  'qux' = 555
} | % getEnumerator | % {
  $_.key
  $_.value
}

Solution 3

here a similare function i used to read ini file.(the value are also a dictionary like yours).

ini file that i transform into hash look like this

[Section1]

key1=value1
key2=value2

[Section2]

key1=value1
key2=value2
key3=value3

From the ini the hashtable look like this (i passed the fonction that do the transformation in to hash):

$Inihash = @{ 
           "Section1" = @{
               "key1" = "value1"
               "key2" = " value2"
           }
           "Section2" = @{
               "key1" = "value1"
               "key2" = "value2"
         "key3" = "value3"
           }
        }

so from the hash table this line will search all the key/value for a given section:

$Inihash.GetEnumerator() |?{$_.Key -eq "Section1"} |% {$_.Value.GetEnumerator() | %{write-host $_.Key "=" $_.Value}} 

? = for search where-object equal my section name. % = you have to do 2 enumeration ! one for all the section and a second for get all the key in the section.

Share:
42,077
Matt Simmons
Author by

Matt Simmons

12+ years administering small/medium networks 18+ years of Linux experience I'm not a programmer, but I've played one on TV. OK, not really, but I did have the title "PHP Programmer" for 6 months. I also write a lot of shell scripts. So I've got that going for me. New stuff since this profile was invented is PowerShell... I run VMs, and love me some PowerCLI.

Updated on October 01, 2020

Comments

  • Matt Simmons
    Matt Simmons over 3 years

    I've got a hash table:

    $myHash = @{ 
       "key1" = @{
           "Entry 1" = "one"
           "Entry 2" = "two"
       }
       "key 2" = @{
           "Entry 1" = "three"
           "Entry 2" = "four"
       }
    }
    

    I'm doing a loop through to get the objects:

    $myHash.keys | ForEach-Object {
        Write-Host $_["Entry 1"]
    }
    

    Works fine, but what can I use to figure out which of the keys of $myHash I'm in? $_.Name doesn't return anything. I'm stumped. Help?

    • Matt Simmons
      Matt Simmons over 11 years
      OK, so I initially left out the ".keys" part of $myHash.keys in the loop both here and in my testing window, even though they were in the actual script. As it turns out, specifying the .keys value does cause it to work. But Graimer's code works too, even with my original mistake, so he gets the checkmark.
  • Matt Simmons
    Matt Simmons over 11 years
    Thanks! I appreciate it. Works well!
  • Jake H
    Jake H over 11 years
    Another common way is: $hash.Keys | %{ "key is: $($_), value is $($hash[$_])" }
  • Frode F.
    Frode F. over 11 years
    It does the same, but requires multiple reads to the hashtable and is more prone to typos
  • Joshua K
    Joshua K about 2 years
    Good use of the pipeline and demonstration of nesting. Thanks! This is an excellent example of the power of powershell.