Search code examples
powershell

Is it possible to reference a psObject/Hashtable name via a variable?


Lets say I have a serious of objects (in pscustomObject or Hashtables) and I need to reference them dynamically, as is it the user that is deciding what data to access.

....
$sweden = [PSCustomObject]@{monday = "sunny" ; tuesday = "sunny" ; wednesday = "sunny" ; thursday = "sunny" ; friday = "sunny"}
$siberia    = [PSCustomObject]@{monday = "cold" ; tuesday = "cold" ; wednesday = "cold" ; thursday = "cold" ; friday = "cold"}
$turkey = [PSCustomObject]@{monday = "unknown" ; tuesday = "unknown" ; wednesday = "cold" ; thursday = "cold" ; friday = "cold"}
$england = [PSCustomObject]@{monday = "miserable" ; tuesday = "miserable" ; wednesday = "miserable" ; thursday = "miserable" ; friday = "miserable"}
....

The user is meant to pass his value to the $country variable, I then need to access corresponding data pool. Something like the following:

$country = 'england'
$("$country").monday #this should print "miserable"

Running the above, nothing happens, no errors. The prompt returns, that is it. I also tried it without the quotes, $($country).monday.

pwsh 7.4/win11


Solution

  • Use a single hashtable instead of multiple variables to reference your countries:

    $countries = @{
        sweden  = [PSCustomObject]@{monday = 'sunny' ; tuesday = 'sunny' ; wednesday = 'sunny' ; thursday = 'sunny' ; friday = 'sunny' }
        siberia = [PSCustomObject]@{monday = 'cold' ; tuesday = 'cold' ; wednesday = 'cold' ; thursday = 'cold' ; friday = 'cold' }
        turkey  = [PSCustomObject]@{monday = 'unknown' ; tuesday = 'unknown' ; wednesday = 'cold' ; thursday = 'cold' ; friday = 'cold' }
        england = [PSCustomObject]@{monday = 'miserable' ; tuesday = 'miserable' ; wednesday = 'miserable' ; thursday = 'miserable' ; friday = 'miserable' }
    }
    
    $country = 'england'
    $countries[$country].monday # this should print "miserable"
    

    The alternative if using multiple variables to dynamically reference it, is to use Get-Variable, which really does feel miserable:

    $country = 'england'
    (Get-Variable $country -ValueOnly).monday