Search code examples
powershellreplaceforeachhashtable

PowerShell update hashtable values in foreach loop


I'm trying to update each value in my hashtable with a string replacement. I tried solutions mentioned here, but to no avail.

My current code generates the values with the required replacement. But how do I get them to replace the values in my hashtable?

$mactable = [ordered]@{
    "A" = "11:22:33:XX:YY:10"
    "B" = "11:22:33:XX:YY:20"
    "C" = "11:22:33:XX:YY:30"
    "D" = "11:22:33:XX:YY:40"
    "E" = "11:22:33:XX:YY:50"
}

$octet4hex = "10"
$octet5hex = "16"

foreach($value in $mactable.values){
    $value -replace "XX:YY", ($octet4hex+":"+$octet5hex)
}

I tried this (as a mentioned solution):

foreach($value in @($mactable.values)){
    $mactable[$key] = $value -replace "XX:YY", ($octet4hex+":"+$octet5hex)
}

But that gives me the following error:

Index operation failed; the array index evaluated to null.

Expected result is:

"A" = "11:22:33:10:16:10"
"B" = "11:22:33:10:16:20"
"C" = "11:22:33:10:16:30"
"D" = "11:22:33:10:16:40"
"E" = "11:22:33:10:16:50"

Solution

  • Since you're using an OrderedDictionary and it supports Item[Int32] you can do it with a for loop:

    for ($i = 0; $i -lt $mactable.Keys.Count; $i++) {
        $value = $mactable[$i] -replace 'XX:YY', ($octet4hex + ':' + $octet5hex)
        $mactable[$i] = $value
    }
    $mactable['E'] # Outputs: 11:22:33:10:16:50
    

    If however you were using a hashtable instead, you would need to clone it or create a new array from its keys like shown in other answers from the link (foreach ($key in @($hash.Keys)) { ..) in order to update it while at the same time enumerating it or you would get the error:

    Collection was modified; enumeration operation may not execute.

    $mactable = @{
        'A' = '11:22:33:XX:YY:10'
        'B' = '11:22:33:XX:YY:20'
        'C' = '11:22:33:XX:YY:30'
        'D' = '11:22:33:XX:YY:40'
        'E' = '11:22:33:XX:YY:50'
    }
    
    foreach ($key in $mactable.Clone().Keys) {
        $value = $mactable[$key] -replace 'XX:YY', ($octet4hex + ':' + $octet5hex)
        $mactable[$key] = $value
    }
    $mactable['E'] # Outputs: 11:22:33:10:16:50