2

Say I have the following environment variables:

a = Poke
b = mon
Pokemon= Feraligatr

I want to be able to concatenate a and b environment variables to get the variable name Pokemon and the get Pokemon value like $($env:ab) or $($env:$($env:a)$($env:b)) (This examples does not work)

5
  • What do environment variables do in your code? Read this article please. What you want to do requires reflection. Please explain WHY exactly you want to do this. What is the purpose of your code. Commented Feb 16, 2023 at 17:07
  • 1
    Does this answer your question? Get the value of an environment variable whose name is stored in a variable The answer is (Get-Item -Path env:\$(($env:a)+($env:b))).Value Commented Feb 16, 2023 at 17:21
  • @Max They do not do anything special, they are just two (a and b) strings passed as parameters and set as environment variables, in order to the get Pokemon environment variable I need to concatenate this two first and key try to get the variable value, Commented Feb 16, 2023 at 17:22
  • 2
    The sub-expressions are not needed. Simply do (Get-Item env:$env:a$env:b).Value. This is easier to read in an editor that does proper syntax highlighting. Alternatively (Get-Item env:"$env:a$env:b").Value Commented Feb 16, 2023 at 17:47
  • That code isn't powershell. Commented Feb 17, 2023 at 21:25

1 Answer 1

1

Building on the helpful comments:

You're looking for indirection, i.e. the ability to refer to an environment variable indirectly, via another (environment) variable(s) storing the target variable's name.


PowerShell-idiomatic solution:

Use the Env: drive in combination with the Get-Content cmdlet:

# The target environment variable.
$env:Pokemon='bingo!'

# The variables that, in combination, return the *name* 
# of the target environment variable.
$env:a = 'Poke'
$env:b = 'mon'

# Use Get-Content and the env: drive to retrieve
# an environment variable by an *indirectly* specified name.
# Note: 
#   * env:$env:a$env:b is treated like "env:$env:a$env:b",
#     i.e. an expandable (interpolating string).
#   * For better visual delineation of the variables, use:
#       env:${env:a}${env:b}
#   * `-ErrorAction Ignore` ignores the case when the target var.
#     doesn't exist (quietly returns $null`)
# -> 'bingo!'
Get-Content -ErrorAction Ignore env:$env:a$env:b 

# Alternative, with explicit string concatenation.
Get-Content -ErrorAction Ignore ('env:' + $env:a + $env:b)

Note:

  • To set environment variables indirectly, use the Set-Content cmdlet; e.g.:

    $varName = 'FOO'
    Set-Content env:$varName BAR # $env:FOO now contains 'BAR'
    
  • Applying the same technique to regular shell variables (non-environment variables), requires either use of the variable: drive, or, for more flexibility, the Get-Variable and Set-Variable cmdlets - see this answer.

  • More more information about expandable (interpolating) string literals such as "env:$env:a$env:b", see the conceptual about_Quoting help topic.


.NET API alternative:

As Max points out, you can also use the static System.Environment.GetEnvironmentVariable .NET method:

[Environment]::GetEnvironmentVariable("${env:a}${env:b}")

For more information about calling .NET API methods from PowerShell, see the conceptual about_Methods help topic.

Sign up to request clarification or add additional context in comments.

2 Comments

Can't you just use the following in powershell? [Environment]::GetEnvironmentVariable("$($env:a)$($env:b)"). That should work as long as the variables already exist, right?
@Max, yes, good point, thanks - I've added your suggestion to your answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.