Accessing Environment Variables in PowerShell

Wed, May 10, 2006 2-minute read

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 > ${[email protected]#[email protected]#[email protected]#[email protected]!} = "Crazy Variable!"

[C:\temp]
PS:32 > ${[email protected]#[email protected]#[email protected]#[email protected]!}
Crazy Variable!

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

Name                           Value
----                           -----
[email protected]#[email protected]#[email protected]#[email protected]!       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.