What is the difference between Env: and [System.Environment]?

Viewed 287
1 Answers

[System.Environment] is the .Net framework's static environment class. It offers static methods related to the "environment" including ways to get environment variables.

$env:WHATEVER is special variable syntax whereby you can access the contents of a PSProvider using variable semantics.

What is a PSProvider? (also see about_Providers)

It's basically a way to access hierarchical data stores through a singular interface that is similar to a filesystem.

In fact FileSystem is itself a PSProvider in PowerShell, and this is why cmdlets that deal with files don't mention files (i.e.: Get-ChildItem, Get-Content, Set-Location, etc.).

To see available providers, use Get-PSProvider:

Name                 Capabilities                                                Drives                                                     
----                 ------------                                                ------                                                     
Registry             ShouldProcess, Transactions                                 {HKLM, HKCU}                                               
Alias                ShouldProcess                                               {Alias}                                                    
Environment          ShouldProcess                                               {Env}                                                      
FileSystem           Filter, ShouldProcess, Credentials                          {A, C, D, P...}                                            
Function             ShouldProcess                                               {Function}                                                 
Variable             ShouldProcess                                               {Variable}                                                 
Certificate          ShouldProcess                                               {Cert}                                                     
WSMan                Credentials                                                 {WSMan}

Use Get-PSDrive to just see the drives themselves:

Name           Used (GB)     Free (GB) Provider      Root                   
----           ---------     --------- --------      ----                   
A                 103.23         46.58 FileSystem    A:\                    
Alias                                  Alias                                
C                 200.02         22.77 FileSystem    C:\                    
Cert                                   Certificate   \                      
D                1048.88       2677.13 FileSystem    D:\                    
Env                                    Environment                          
Function                               Function                             
HKCU                                   Registry      HKEY_CURRENT_USER      
HKLM                                   Registry      HKEY_LOCAL_MACHINE     
O                  49.34         10.16 FileSystem    O:\                    
P                 335.32        176.50 FileSystem    P:\                    
S                                      FileSystem    S:\                    
Variable                               Variable                             
WSMan                                  WSMan

Environment is also a PSProvider, which you can see by trying to navigate to its PSDrive:

Set-Location Env:

Or browsing it:

Get-ChildItem Env:

Or even getting its contents:

Get-Content Env:\COMPUTERNAME
Get-ChildItem Env: | Get-Content

The special variable syntax is a shorthand way of accessing certain PSProviders (they don't all support it), and it's most often used with Environment (I'd venture a guess that syntax was created specifically for the Environment).

That syntax does actually work for the file system but it's pretty awkward

${C:\users\briantist\test.txt}

Tab completion doesn't work correctly with that syntax.

If you try it for something like the registry provider, it will tab complete but throw an exception about it not being implemented when you run it.

Here's a fun useless one: use the Variable:\ provider:

$test = 'test'
$Variable:test
Related