4

I have some variables that i need to get the value from, the thing is that in the middle of the name i can have any possible value because it's the artifacts name.

Example: I have these environment variables: RELEASE_ARTIFACTS__TESTECOMPLETEPR__PROJECTNAME RELEASE_ARTIFACTS__TESTECOMPLETEPR_REPOSITORY_NAME

And i need something like: $repoId = (Get-Item -Path Env:RELEASE_ARTIFACTS_*_REPOSITORY_ID).Value or $repoId = $Env:RELEASE_ARTIFACTS_*_REPOSITORY_ID

But the * doesn't seem to work. How can i do this?

1 Answer 1

4

Wildcard expressions are supported, with all providers, in the -Path parameter of the Get-Item cmdlet, and also with Get-Content, which is preferable here because it returns the environment-variable value directly (no need for (...).Value); to demonstrate:

$env:RELEASE_ARTIFACTS_FOO_REPOSITORY_ID = 1

Get-Content env:RELEASE_ARTIFACTS_*_REPOSITORY_ID # -> 1

Perhaps surprisingly, they are also supported when you use namespace variable notation, though you must then enclose the reference in {...} (because a * would otherwise not be recognized as part of a variable name):

${env:RELEASE_ARTIFACTS_*_REPOSITORY_ID} # -> 1

Caveats:Tip of the hat to Daniel.

  • If the wildcard pattern matches multiple items (environment variables in this case), a statement-terminating error occurs. Use the Get-Content (or Get-Item) approach to retrieve multiple values (items).

    • Given this awkwardness, along with the escaping pitfalls discussed below, it would make sense not to support wildcard matching in namespace variable notation, as suggested in GitHub issue #9225; while technically a breaking change, my sense is that not much real-world code would be impacted.
  • Strangely, namespace variable notation with wildcard patterns does not work with variables (where the notation is rarely used to begin with, however, given that $variable:foo offers no advantage over $foo): ${variable:HOM*} performs no wildcard matching and behaves like an undefined variable (it quietly evaluates to $null by default).

    • While the Get-Content / Get-Item approach does work, note that there's also a dedicated Get-Variable cmdlet (use -ValueOnly to get just the value) - e.g. Get-Variable HOM* -ValueOnly - which additionally supports accessing variables in different scopes, via the -Scope parameter.

Namespace variable notation vs. Get-Content:

  • Namespace variable notation is both more concise and performs better (because a cmdlet call isn't involved).

  • However, the Get-Content approach is sometimes required, namely when you use a variable to specify the environment-variable name or name pattern; that is, assuming variable definition $envVarName = 'RELEASE_ARTIFACTS_*_REPOSITORY_ID':

    • ${env:$envVarName} does not work,
    • but Get-Content env:$envVarName does.
  • Escaping pitfalls:

    • Escaping wildcard metacharacters such as [ that you want to be interpreted verbatim is currently challenging, due to the bugs discussed in this answer.

    • If the whole name should be used verbatim, you can avoid the need for escaping by using Get-Content's -LiteralPath parameter instead; however, this isn't an option with namespace variable notation, where names are invariably treated as wildcard patterns.

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

1 Comment

Thank you, @Daniel - excellent points. I've added the info to the answer, with some extra commentary. ${variable:PSVer*Table} not working is at the very least a strange inconsistency, though in the grand scheme of things I think it would have been wiser never to support wildcard matching in namespace variable to begin with; that is, ${env:someName} should always have been the equivalent of Get-Content -LiteralPath env:someName, not Get-Content -Path env:someName` - that also solves the awkwardness of the error occurring with multiple matches - see the linked GitHub issue.

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.