Accessing Environment Variables in PowerShell

In a recent comment, David asked how to access environment variables in PowerShell.  This is something that we normally just document explicitly: $env:Variable


However, that explicit documentation is actually a shortcut for a feature you may not know about.  It’s a little like dividing fractions – you can do it without ever knowing why it works, just that it works.  Of course, it’s nice to be able to explain why.


As you may know, the ‘$’ character is the way that we access variables in PowerShell.  The probing student might then ask, “Why can we access environment variables the same way we access normal variables.  Isn’t ‘Env:’ the environment provider?  And specific environment variables are children of it?”


Those are good questions.  This is because the Environment provider shares something in common with several other providers – namely support for the *-Content set of core Cmdlets:



[C:\temp]
PS:11 > “hello world” > test


[C:\temp]
PS:12 > get-content test
hello world


[C:\temp]
PS:13 > get-content variable:ErrorActionPreference
Continue


[C:\temp]
PS:14 > get-content function:more
param([string[]]$paths);  if(($paths -ne $null) -and ($paths.length -ne 0))  { …
       Get-Content $local:file | Out-Host -p    }  }  else { $input | Out-Host …


[C:\temp]
PS:15 > get-content env:systemroot
C:\WINDOWS


For providers that support the content cmdets, we let you interact with this content through a special variable syntax:



[C:\temp]
PS:16 > $function:more
param([string[]]$paths);  if(($paths -ne $null) -and ($paths.length -ne 0))  { …
       Get-Content $local:file | Out-Host -p    }  }  else { $input | Out-Host …


[C:\temp]
PS:17 > $variable:ErrorActionPreference
Continue


[C:\temp]
PS:18 > $c:test
hello world


[C:\temp]
PS:19 > $env:systemroot
C:\WINDOWS


This variable syntax for content management allows you to both get, and set content:



[C:\temp]
PS:20> $function:more = { $input | less.exe }


[C:\temp]
PS:21> $function:more
$input | less.exe


Now, when it comes to accessing complex provider paths using this method, you’ll quickly run into naming issues:



[C:\temp]
PS:22> $c:\temp\test.txt
Unexpected token ‘\temp\test.txt’ in expression or statement.
At line:1 char:17
+ $c:\temp\test.txt <<<<


The solution to that lies in our escaping support for complex variable names:


[C:\temp]
PS:31 > ${1234123!@#$!@#$12$!@#$@!} = “Crazy Variable!”


[C:\temp]
PS:32 > ${1234123!@#$!@#$12$!@#$@!}
Crazy Variable!


[C:\temp]
PS:33 > dir variable:\1*


Name                           Value
—-                           —–
1234123!@#$!@#$12$!@#$@!       Crazy Variable!


… and the content equivalent:



[C:\temp]
PS:34 > ${c:\temp\test.txt}
hello world


So, the way to access environment variables isn’t so unique after all. 

4 Responses to “Accessing Environment Variables in PowerShell”

  1. Jeffrey Snover writes:

    PSMDTAG:FAQ: Environment Variables – how I access them? ANSWER: $ENV:VAR

    PSMDTAG:FAQ: How do use ANY character in a variable name? ANSWER: ${ any chars}=value

    PSMDTAG:INTERNAL: Environmental variables exposed as a namespace drive.

    Jeffrey Snover [MSFT]
    Windows PowerShell/Aspen Architect
    Visit the Windows PowerShell Team blog at: http://blogs.msdn.com/PowerShell
    Visit the Windows PowerShell ScriptCenter at: http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

  2. bin writes:

    I met a problem when I want to run a sequence of batch files in PowerShell. The envioronment variables did not pass between batch files as well as did not pass to PS $env:

    PS D:\myworkspace> gc a.bat
    set mypath=c:\WINDOWS
    PS D:\myworkspace> gc b.bat
    cd %mypath%
    PS D:\myworkspace> .\a.bat

    D:\myworkspace>set mypath=c:\WINDOWS
    PS D:\myworkspace> .\b.bat

    D:\myworkspace>cd
    D:\myworkspace
    PS D:\myworkspace> $env:mypath
    PS D:\myworkspace>

  3. Lee writes:

    Yes — this is because PowerShell loads cmd.exe as a child process (as does cmd.exe if you call it explicitly.) See this post for info about that problem, and the solution: http://www.leeholmes.com/blog/NothingSolvesEverythingPowerShellAndOtherTechnologies.aspx

    Lee

  4. Protecting your Virtual Machines From “That Guy” writes:

    [...] http://www.leeholmes.com/blog/2006/05/10/accessing-environment-variables-in-powershell/ [...]

Leave a Reply