[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