How to assign and reference environment variables containing square brackets in PowershellWhat type of object is $<drivename>: (such as `$code:`) in Powershell?Setting environment variables on OS XHow do I iterate over a range of numbers defined by variables in Bash?How to concatenate string variables in BashRead environment variables in Node.jsHow to access environment variable values?List all environment variables from command line?How do I delete an exported environment variable?How do you comment out code in PowerShell?Setting an environment variable before a command in bash not working for second command in a pipeHow do I pass environment variables to Docker containers?

What does "another" mean in this case?

How frequently do Russian people still refer to others by their patronymic (отчество)?

Should I cheat if the majority does it?

My mother co-signed for my car. Can she take it away from me if I am the one making car payments?

What is meaning of 4 letter acronyms in Roman names like Titus Flavius T. f. T. n. Sabinus?

How is /a/ pronounced before n/m in French?

Are there advantages in writing by hand over typing out a story?

What is a "tittering order"?

What is the right way to query an I2C device from an interrupt service routine?

Show that there are infinitely more problems than we will ever be able to compute

What is the difference between case and adpositions?

Is my background sufficient to start Quantum Computing

How can I know (without going to the station) if RATP is offering the Anti Pollution tickets?

Is it advisable to inform the CEO about his brother accessing his office?

Can the word "coexist" be used for more than two things/people/subjects/... etc?

Will greasing clutch parts make it softer

Can you use a reaction to affect initiative rolls?

How to widen the page

Solving Equations with HeavisideTheta Functions

Which are more efficient in putting out wildfires: planes or helicopters?

Isn't "Dave's protocol" good if only the database, and not the code, is leaked?

Who are the police in Hong Kong?

Has there ever been a cold war other than between the U.S. and the U.S.S.R.?

Did Snape really give Umbridge a fake Veritaserum potion that Harry later pretended to drink?



How to assign and reference environment variables containing square brackets in Powershell


What type of object is $<drivename>: (such as `$code:`) in Powershell?Setting environment variables on OS XHow do I iterate over a range of numbers defined by variables in Bash?How to concatenate string variables in BashRead environment variables in Node.jsHow to access environment variable values?List all environment variables from command line?How do I delete an exported environment variable?How do you comment out code in PowerShell?Setting an environment variable before a command in bash not working for second command in a pipeHow do I pass environment variables to Docker containers?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








2















When the PSDrive is not specified, the following works:



$[foo]="bar"
echo $[foo]


But the following does not work



$env:$[foo]="bar"
At line:1 char:1
+ $env:$[foo]="bar"
+ ~~~~~
Variable reference is not valid. ':' was not followed by a valid variable name character. Consider using $ to delimit the name.
At line:1 char:6
+ $env:$[foo]="bar"
+ ~~~~~~~~~~~~~~
Unexpected token '$[foo]="bar"' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : InvalidVariableReferenceWithDrive


$env:[foo]="bar"
Cannot find path 'env:[foo]' because it does not exist.
At line:1 char:1
+ $env:[foo]="bar"
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (env:[foo]:String) [], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound


The following works, though I am curious if there's short hand syntax for it:



Set-Item -LiteralPath env:$[foo] -Value "bar"
Get-Item -LiteralPath env:$[foo] | % $_.Value


However the following does not work:



Set-Item -LiteralPath env:$[foo]2 -Value "bar"
Set-Item : Cannot process argument because the value of argument "name" is null. Change the value of argument "name" to a non-null value.
At line:1 char:1
+ Set-Item -LiteralPath env:$[foo]2 -Value "bar"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:String) [Set-Item], PSArgumentNullException
+ FullyQualifiedErrorId : SetItemNullName,Microsoft.PowerShell.Commands.SetItemCommand









share|improve this question
























  • Great question; as an aside: Get-Item -LiteralPath env:$[foo] and Set-Item -LiteralPath env:$[foo] -Value "bar" do not work either, or at least won't work they way you expect, due to up-front string expansion.

    – mklement0
    Mar 25 at 19:50

















2















When the PSDrive is not specified, the following works:



$[foo]="bar"
echo $[foo]


But the following does not work



$env:$[foo]="bar"
At line:1 char:1
+ $env:$[foo]="bar"
+ ~~~~~
Variable reference is not valid. ':' was not followed by a valid variable name character. Consider using $ to delimit the name.
At line:1 char:6
+ $env:$[foo]="bar"
+ ~~~~~~~~~~~~~~
Unexpected token '$[foo]="bar"' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : InvalidVariableReferenceWithDrive


$env:[foo]="bar"
Cannot find path 'env:[foo]' because it does not exist.
At line:1 char:1
+ $env:[foo]="bar"
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (env:[foo]:String) [], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound


The following works, though I am curious if there's short hand syntax for it:



Set-Item -LiteralPath env:$[foo] -Value "bar"
Get-Item -LiteralPath env:$[foo] | % $_.Value


However the following does not work:



Set-Item -LiteralPath env:$[foo]2 -Value "bar"
Set-Item : Cannot process argument because the value of argument "name" is null. Change the value of argument "name" to a non-null value.
At line:1 char:1
+ Set-Item -LiteralPath env:$[foo]2 -Value "bar"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:String) [Set-Item], PSArgumentNullException
+ FullyQualifiedErrorId : SetItemNullName,Microsoft.PowerShell.Commands.SetItemCommand









share|improve this question
























  • Great question; as an aside: Get-Item -LiteralPath env:$[foo] and Set-Item -LiteralPath env:$[foo] -Value "bar" do not work either, or at least won't work they way you expect, due to up-front string expansion.

    – mklement0
    Mar 25 at 19:50













2












2








2


1






When the PSDrive is not specified, the following works:



$[foo]="bar"
echo $[foo]


But the following does not work



$env:$[foo]="bar"
At line:1 char:1
+ $env:$[foo]="bar"
+ ~~~~~
Variable reference is not valid. ':' was not followed by a valid variable name character. Consider using $ to delimit the name.
At line:1 char:6
+ $env:$[foo]="bar"
+ ~~~~~~~~~~~~~~
Unexpected token '$[foo]="bar"' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : InvalidVariableReferenceWithDrive


$env:[foo]="bar"
Cannot find path 'env:[foo]' because it does not exist.
At line:1 char:1
+ $env:[foo]="bar"
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (env:[foo]:String) [], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound


The following works, though I am curious if there's short hand syntax for it:



Set-Item -LiteralPath env:$[foo] -Value "bar"
Get-Item -LiteralPath env:$[foo] | % $_.Value


However the following does not work:



Set-Item -LiteralPath env:$[foo]2 -Value "bar"
Set-Item : Cannot process argument because the value of argument "name" is null. Change the value of argument "name" to a non-null value.
At line:1 char:1
+ Set-Item -LiteralPath env:$[foo]2 -Value "bar"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:String) [Set-Item], PSArgumentNullException
+ FullyQualifiedErrorId : SetItemNullName,Microsoft.PowerShell.Commands.SetItemCommand









share|improve this question
















When the PSDrive is not specified, the following works:



$[foo]="bar"
echo $[foo]


But the following does not work



$env:$[foo]="bar"
At line:1 char:1
+ $env:$[foo]="bar"
+ ~~~~~
Variable reference is not valid. ':' was not followed by a valid variable name character. Consider using $ to delimit the name.
At line:1 char:6
+ $env:$[foo]="bar"
+ ~~~~~~~~~~~~~~
Unexpected token '$[foo]="bar"' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : InvalidVariableReferenceWithDrive


$env:[foo]="bar"
Cannot find path 'env:[foo]' because it does not exist.
At line:1 char:1
+ $env:[foo]="bar"
+ ~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (env:[foo]:String) [], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound


The following works, though I am curious if there's short hand syntax for it:



Set-Item -LiteralPath env:$[foo] -Value "bar"
Get-Item -LiteralPath env:$[foo] | % $_.Value


However the following does not work:



Set-Item -LiteralPath env:$[foo]2 -Value "bar"
Set-Item : Cannot process argument because the value of argument "name" is null. Change the value of argument "name" to a non-null value.
At line:1 char:1
+ Set-Item -LiteralPath env:$[foo]2 -Value "bar"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:String) [Set-Item], PSArgumentNullException
+ FullyQualifiedErrorId : SetItemNullName,Microsoft.PowerShell.Commands.SetItemCommand






powershell syntax namespaces environment-variables






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 25 at 19:56









mklement0

148k24 gold badges269 silver badges303 bronze badges




148k24 gold badges269 silver badges303 bronze badges










asked Mar 25 at 17:52









cdmihaicdmihai

1,8102 gold badges15 silver badges14 bronze badges




1,8102 gold badges15 silver badges14 bronze badges












  • Great question; as an aside: Get-Item -LiteralPath env:$[foo] and Set-Item -LiteralPath env:$[foo] -Value "bar" do not work either, or at least won't work they way you expect, due to up-front string expansion.

    – mklement0
    Mar 25 at 19:50

















  • Great question; as an aside: Get-Item -LiteralPath env:$[foo] and Set-Item -LiteralPath env:$[foo] -Value "bar" do not work either, or at least won't work they way you expect, due to up-front string expansion.

    – mklement0
    Mar 25 at 19:50
















Great question; as an aside: Get-Item -LiteralPath env:$[foo] and Set-Item -LiteralPath env:$[foo] -Value "bar" do not work either, or at least won't work they way you expect, due to up-front string expansion.

– mklement0
Mar 25 at 19:50





Great question; as an aside: Get-Item -LiteralPath env:$[foo] and Set-Item -LiteralPath env:$[foo] -Value "bar" do not work either, or at least won't work they way you expect, due to up-front string expansion.

– mklement0
Mar 25 at 19:50












1 Answer
1






active

oldest

votes


















5














Written as of PowerShell Core 6.2.0



The reason is that PowerShell treats the following:



$<drive>:<name>


as if you had specified:



Get-Content -Path <drive>:<name> # or, with assignment, Set-Content -Path ...


This notation - though often used with the Env: drive (e.g., $env:Path) - is little-known as a general paradigm named namespace variable notation, which is explained in this answer.



The problem is the use of -Path rather than -LiteralPath, because -Path interprets its argument as a wildcard expression.



Therefore, the [foo] in $env:[foo] - rather than being used as-is - is interpreted as a wildcard expression that matches a single character that is either f or o ([foo] is a character set or range ([...]) that matches any one of the (distinct) characters inside - see about_Wildcards).



On assigning to $env:[foo], the logic of Set-Content -Path requires that a wildcard-based path resolve to something existing, even though you're generally not required to explicitly create environment variables; e.g., $env:NoSuchVarExistsYet = 'new' works just fine.




Workaround:



Use double(!)-`-escaping of the wildcard metacharacters:



# Namespace variable notation only works with if you
# double(!)-backtick-escape the wildcard metacharacters:

# Assign to / implicitly create env. var '[foo]'
$env:``[foo``] = 'bar'

# Get its value.
$env:``[foo``]


Note:



  • Escaping shouldn't be required at all, because there is no good reason to treat paths that conceptually identify a given, known item as wildcard expressions - see this GitHub issue.


  • That double `-escaping is needed is an added quirk - see this GitHub issue.


  • Another workaround - one that doesn't involve escaping - is to use
    Set-Content -LiteralPath env:[foo] bar and Get-Content -LiteralPath env:[foo], but that is both verbose and slow.



As for the other syntax variations you tried:




$env:$[foo]="bar"




Since your variable reference isn't ...-enclosed as a whole (except for the initial $), the token that follows the : is only allowed to contain characters that do not require escaping - and $, and all violate that rule.




  • ...-enclosing the entire path - $env:[foo] - solves the syntax problem, but runs into the problem detailed above.


Set-Item -LiteralPath env:$[foo] -Value "bar"




This does not work in general, because string expansion is applied beforehand here - it is as if you had passed "env:$[foo]": the reference to a (regular) variable named $[foo] is expanded (replaced with its value) and in effect appended to literal env:, before handing the result to Set-Item.



If such a regular variable doesn't exist, what Set-Item sees is just env: (because non-existent variables default to $null, which becomes the empty string in a string context), which causes an error due to the lack of variable name.



By contrast, the following would set an environment variable named unrelated instead:



# Create a regular variable literally named '[foo]'.
$[foo] = 'unrelated'

# !! The following sets env:unrelated, i.e., env. var 'unrelated',
# !! due to the string expansion that is performed on the -LiteralPath
# !! argument up front.
Set-Item -LiteralPath env:$[foo] bar

$env:unrelated # -> 'bar'


The same applies to Get-Item -LiteralPath env:$[foo] and
Set-Item -LiteralPath env:$[foo]2 -Value "bar".






share|improve this answer
























    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55343828%2fhow-to-assign-and-reference-environment-variables-containing-square-brackets-in%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    5














    Written as of PowerShell Core 6.2.0



    The reason is that PowerShell treats the following:



    $<drive>:<name>


    as if you had specified:



    Get-Content -Path <drive>:<name> # or, with assignment, Set-Content -Path ...


    This notation - though often used with the Env: drive (e.g., $env:Path) - is little-known as a general paradigm named namespace variable notation, which is explained in this answer.



    The problem is the use of -Path rather than -LiteralPath, because -Path interprets its argument as a wildcard expression.



    Therefore, the [foo] in $env:[foo] - rather than being used as-is - is interpreted as a wildcard expression that matches a single character that is either f or o ([foo] is a character set or range ([...]) that matches any one of the (distinct) characters inside - see about_Wildcards).



    On assigning to $env:[foo], the logic of Set-Content -Path requires that a wildcard-based path resolve to something existing, even though you're generally not required to explicitly create environment variables; e.g., $env:NoSuchVarExistsYet = 'new' works just fine.




    Workaround:



    Use double(!)-`-escaping of the wildcard metacharacters:



    # Namespace variable notation only works with if you
    # double(!)-backtick-escape the wildcard metacharacters:

    # Assign to / implicitly create env. var '[foo]'
    $env:``[foo``] = 'bar'

    # Get its value.
    $env:``[foo``]


    Note:



    • Escaping shouldn't be required at all, because there is no good reason to treat paths that conceptually identify a given, known item as wildcard expressions - see this GitHub issue.


    • That double `-escaping is needed is an added quirk - see this GitHub issue.


    • Another workaround - one that doesn't involve escaping - is to use
      Set-Content -LiteralPath env:[foo] bar and Get-Content -LiteralPath env:[foo], but that is both verbose and slow.



    As for the other syntax variations you tried:




    $env:$[foo]="bar"




    Since your variable reference isn't ...-enclosed as a whole (except for the initial $), the token that follows the : is only allowed to contain characters that do not require escaping - and $, and all violate that rule.




    • ...-enclosing the entire path - $env:[foo] - solves the syntax problem, but runs into the problem detailed above.


    Set-Item -LiteralPath env:$[foo] -Value "bar"




    This does not work in general, because string expansion is applied beforehand here - it is as if you had passed "env:$[foo]": the reference to a (regular) variable named $[foo] is expanded (replaced with its value) and in effect appended to literal env:, before handing the result to Set-Item.



    If such a regular variable doesn't exist, what Set-Item sees is just env: (because non-existent variables default to $null, which becomes the empty string in a string context), which causes an error due to the lack of variable name.



    By contrast, the following would set an environment variable named unrelated instead:



    # Create a regular variable literally named '[foo]'.
    $[foo] = 'unrelated'

    # !! The following sets env:unrelated, i.e., env. var 'unrelated',
    # !! due to the string expansion that is performed on the -LiteralPath
    # !! argument up front.
    Set-Item -LiteralPath env:$[foo] bar

    $env:unrelated # -> 'bar'


    The same applies to Get-Item -LiteralPath env:$[foo] and
    Set-Item -LiteralPath env:$[foo]2 -Value "bar".






    share|improve this answer





























      5














      Written as of PowerShell Core 6.2.0



      The reason is that PowerShell treats the following:



      $<drive>:<name>


      as if you had specified:



      Get-Content -Path <drive>:<name> # or, with assignment, Set-Content -Path ...


      This notation - though often used with the Env: drive (e.g., $env:Path) - is little-known as a general paradigm named namespace variable notation, which is explained in this answer.



      The problem is the use of -Path rather than -LiteralPath, because -Path interprets its argument as a wildcard expression.



      Therefore, the [foo] in $env:[foo] - rather than being used as-is - is interpreted as a wildcard expression that matches a single character that is either f or o ([foo] is a character set or range ([...]) that matches any one of the (distinct) characters inside - see about_Wildcards).



      On assigning to $env:[foo], the logic of Set-Content -Path requires that a wildcard-based path resolve to something existing, even though you're generally not required to explicitly create environment variables; e.g., $env:NoSuchVarExistsYet = 'new' works just fine.




      Workaround:



      Use double(!)-`-escaping of the wildcard metacharacters:



      # Namespace variable notation only works with if you
      # double(!)-backtick-escape the wildcard metacharacters:

      # Assign to / implicitly create env. var '[foo]'
      $env:``[foo``] = 'bar'

      # Get its value.
      $env:``[foo``]


      Note:



      • Escaping shouldn't be required at all, because there is no good reason to treat paths that conceptually identify a given, known item as wildcard expressions - see this GitHub issue.


      • That double `-escaping is needed is an added quirk - see this GitHub issue.


      • Another workaround - one that doesn't involve escaping - is to use
        Set-Content -LiteralPath env:[foo] bar and Get-Content -LiteralPath env:[foo], but that is both verbose and slow.



      As for the other syntax variations you tried:




      $env:$[foo]="bar"




      Since your variable reference isn't ...-enclosed as a whole (except for the initial $), the token that follows the : is only allowed to contain characters that do not require escaping - and $, and all violate that rule.




      • ...-enclosing the entire path - $env:[foo] - solves the syntax problem, but runs into the problem detailed above.


      Set-Item -LiteralPath env:$[foo] -Value "bar"




      This does not work in general, because string expansion is applied beforehand here - it is as if you had passed "env:$[foo]": the reference to a (regular) variable named $[foo] is expanded (replaced with its value) and in effect appended to literal env:, before handing the result to Set-Item.



      If such a regular variable doesn't exist, what Set-Item sees is just env: (because non-existent variables default to $null, which becomes the empty string in a string context), which causes an error due to the lack of variable name.



      By contrast, the following would set an environment variable named unrelated instead:



      # Create a regular variable literally named '[foo]'.
      $[foo] = 'unrelated'

      # !! The following sets env:unrelated, i.e., env. var 'unrelated',
      # !! due to the string expansion that is performed on the -LiteralPath
      # !! argument up front.
      Set-Item -LiteralPath env:$[foo] bar

      $env:unrelated # -> 'bar'


      The same applies to Get-Item -LiteralPath env:$[foo] and
      Set-Item -LiteralPath env:$[foo]2 -Value "bar".






      share|improve this answer



























        5












        5








        5







        Written as of PowerShell Core 6.2.0



        The reason is that PowerShell treats the following:



        $<drive>:<name>


        as if you had specified:



        Get-Content -Path <drive>:<name> # or, with assignment, Set-Content -Path ...


        This notation - though often used with the Env: drive (e.g., $env:Path) - is little-known as a general paradigm named namespace variable notation, which is explained in this answer.



        The problem is the use of -Path rather than -LiteralPath, because -Path interprets its argument as a wildcard expression.



        Therefore, the [foo] in $env:[foo] - rather than being used as-is - is interpreted as a wildcard expression that matches a single character that is either f or o ([foo] is a character set or range ([...]) that matches any one of the (distinct) characters inside - see about_Wildcards).



        On assigning to $env:[foo], the logic of Set-Content -Path requires that a wildcard-based path resolve to something existing, even though you're generally not required to explicitly create environment variables; e.g., $env:NoSuchVarExistsYet = 'new' works just fine.




        Workaround:



        Use double(!)-`-escaping of the wildcard metacharacters:



        # Namespace variable notation only works with if you
        # double(!)-backtick-escape the wildcard metacharacters:

        # Assign to / implicitly create env. var '[foo]'
        $env:``[foo``] = 'bar'

        # Get its value.
        $env:``[foo``]


        Note:



        • Escaping shouldn't be required at all, because there is no good reason to treat paths that conceptually identify a given, known item as wildcard expressions - see this GitHub issue.


        • That double `-escaping is needed is an added quirk - see this GitHub issue.


        • Another workaround - one that doesn't involve escaping - is to use
          Set-Content -LiteralPath env:[foo] bar and Get-Content -LiteralPath env:[foo], but that is both verbose and slow.



        As for the other syntax variations you tried:




        $env:$[foo]="bar"




        Since your variable reference isn't ...-enclosed as a whole (except for the initial $), the token that follows the : is only allowed to contain characters that do not require escaping - and $, and all violate that rule.




        • ...-enclosing the entire path - $env:[foo] - solves the syntax problem, but runs into the problem detailed above.


        Set-Item -LiteralPath env:$[foo] -Value "bar"




        This does not work in general, because string expansion is applied beforehand here - it is as if you had passed "env:$[foo]": the reference to a (regular) variable named $[foo] is expanded (replaced with its value) and in effect appended to literal env:, before handing the result to Set-Item.



        If such a regular variable doesn't exist, what Set-Item sees is just env: (because non-existent variables default to $null, which becomes the empty string in a string context), which causes an error due to the lack of variable name.



        By contrast, the following would set an environment variable named unrelated instead:



        # Create a regular variable literally named '[foo]'.
        $[foo] = 'unrelated'

        # !! The following sets env:unrelated, i.e., env. var 'unrelated',
        # !! due to the string expansion that is performed on the -LiteralPath
        # !! argument up front.
        Set-Item -LiteralPath env:$[foo] bar

        $env:unrelated # -> 'bar'


        The same applies to Get-Item -LiteralPath env:$[foo] and
        Set-Item -LiteralPath env:$[foo]2 -Value "bar".






        share|improve this answer















        Written as of PowerShell Core 6.2.0



        The reason is that PowerShell treats the following:



        $<drive>:<name>


        as if you had specified:



        Get-Content -Path <drive>:<name> # or, with assignment, Set-Content -Path ...


        This notation - though often used with the Env: drive (e.g., $env:Path) - is little-known as a general paradigm named namespace variable notation, which is explained in this answer.



        The problem is the use of -Path rather than -LiteralPath, because -Path interprets its argument as a wildcard expression.



        Therefore, the [foo] in $env:[foo] - rather than being used as-is - is interpreted as a wildcard expression that matches a single character that is either f or o ([foo] is a character set or range ([...]) that matches any one of the (distinct) characters inside - see about_Wildcards).



        On assigning to $env:[foo], the logic of Set-Content -Path requires that a wildcard-based path resolve to something existing, even though you're generally not required to explicitly create environment variables; e.g., $env:NoSuchVarExistsYet = 'new' works just fine.




        Workaround:



        Use double(!)-`-escaping of the wildcard metacharacters:



        # Namespace variable notation only works with if you
        # double(!)-backtick-escape the wildcard metacharacters:

        # Assign to / implicitly create env. var '[foo]'
        $env:``[foo``] = 'bar'

        # Get its value.
        $env:``[foo``]


        Note:



        • Escaping shouldn't be required at all, because there is no good reason to treat paths that conceptually identify a given, known item as wildcard expressions - see this GitHub issue.


        • That double `-escaping is needed is an added quirk - see this GitHub issue.


        • Another workaround - one that doesn't involve escaping - is to use
          Set-Content -LiteralPath env:[foo] bar and Get-Content -LiteralPath env:[foo], but that is both verbose and slow.



        As for the other syntax variations you tried:




        $env:$[foo]="bar"




        Since your variable reference isn't ...-enclosed as a whole (except for the initial $), the token that follows the : is only allowed to contain characters that do not require escaping - and $, and all violate that rule.




        • ...-enclosing the entire path - $env:[foo] - solves the syntax problem, but runs into the problem detailed above.


        Set-Item -LiteralPath env:$[foo] -Value "bar"




        This does not work in general, because string expansion is applied beforehand here - it is as if you had passed "env:$[foo]": the reference to a (regular) variable named $[foo] is expanded (replaced with its value) and in effect appended to literal env:, before handing the result to Set-Item.



        If such a regular variable doesn't exist, what Set-Item sees is just env: (because non-existent variables default to $null, which becomes the empty string in a string context), which causes an error due to the lack of variable name.



        By contrast, the following would set an environment variable named unrelated instead:



        # Create a regular variable literally named '[foo]'.
        $[foo] = 'unrelated'

        # !! The following sets env:unrelated, i.e., env. var 'unrelated',
        # !! due to the string expansion that is performed on the -LiteralPath
        # !! argument up front.
        Set-Item -LiteralPath env:$[foo] bar

        $env:unrelated # -> 'bar'


        The same applies to Get-Item -LiteralPath env:$[foo] and
        Set-Item -LiteralPath env:$[foo]2 -Value "bar".







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Mar 25 at 21:32

























        answered Mar 25 at 18:07









        mklement0mklement0

        148k24 gold badges269 silver badges303 bronze badges




        148k24 gold badges269 silver badges303 bronze badges


















            Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.







            Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.



















            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55343828%2fhow-to-assign-and-reference-environment-variables-containing-square-brackets-in%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            SQL error code 1064 with creating Laravel foreign keysForeign key constraints: When to use ON UPDATE and ON DELETEDropping column with foreign key Laravel error: General error: 1025 Error on renameLaravel SQL Can't create tableLaravel Migration foreign key errorLaravel php artisan migrate:refresh giving a syntax errorSQLSTATE[42S01]: Base table or view already exists or Base table or view already exists: 1050 Tableerror in migrating laravel file to xampp serverSyntax error or access violation: 1064:syntax to use near 'unsigned not null, modelName varchar(191) not null, title varchar(191) not nLaravel cannot create new table field in mysqlLaravel 5.7:Last migration creates table but is not registered in the migration table

            용인 삼성생명 블루밍스 목차 통계 역대 감독 선수단 응원단 경기장 같이 보기 외부 링크 둘러보기 메뉴samsungblueminx.comeh선수 명단용인 삼성생명 블루밍스용인 삼성생명 블루밍스ehsamsungblueminx.comeheheheh

            155 수학 과학 기타 둘러보기 메뉴eh추가해eh문서를 완성해