Prof. Powershell

Pushing the ENV:

The Environment PSProvider gives you access to system environmental variables and can be viewed like a drive.

We often use variables in PowerShell as placeholders for values that might change. The advantage is that you can rerun a long or complex code sample simply by changing the value of variables. One source of variables that you may not be using is the Environment PSProvider. This provider gives you access to the system environmental variables like %PATH% and %TEMP%.

In PowerShell, the Environment PSProvider creates an ENV PSDrive which you can view like any other drive. Remember, anytime you want to reference a PSDrive as a drive, include the colon:

PS C:\> dir env:

Name                      Value
----                      -----
ALLUSERSPROFILE           C:\ProgramData
APPDATA                   C:\Users\Jeff\AppData\Roaming
CLASSPATH                 .;C:\Program Files (x86)\
                          QuickTime\QTSystem\QTJava.zip
CommonProgramFiles        C:\Program Files\Common Files
CommonProgramFiles(x86)   C:\Program Files (x86)\Common Files
...

Anything you see here should be the same thing you would see when using a CMD prompt from running SET. In this lesson we're just going to focus on using these values. Over the years I've seen people try to use these values in a number of ways:

PS C:\> $user = get-item -Path env:username | select -ExpandProperty Value
PS C:\> $user
Jeff

Or you might see this:

PS C:\> $user = (get-item -Path env:username).value

Technically there's nothing wrong with this approach as you are, in fact, retrieving the Username item from the ENV: drive. But to me that seems like a lot of work.

Instead we can use a shortcut to retrieve an environmental variable. Personally, I prefer this approach:

PS C:\> $env:username
Jeff

You can interpret that as telling PowerShell to get the value of $ENV:Username and treat the whole thing as a variable. That is a whole lot less to type. But be careful when using these values, especially when combining. Use double-quotes so you can take advantage of variable expansion:

PS C:\> Write-Host "Connecting as $env:userdomain\$env:username" -ForegroundColor Cyan
Connecting as Serenity\Jeff

Or use the -f formatting operator:

PS C:\> $msg = "Connecting as {0}\{1}" -f $env:userdomain,$env:username
PS C:\> Write-Host $msg -ForegroundColor Cyan

Using the environmental variables is also a great way build paths. But don't try to concatenate; instead, use Join-Path:

PS C:\> $myfile = join-path -Path $env:temp -ChildPath MyTemp.txt
PS C:\> $myfile
C:\Users\Jeff\AppData\Local\Temp\MyTemp.txt
PS C:\> $docs = Join-Path -Path $env:USERPROFILE -ChildPath Documents
C:\Users\Jeff\Documents

My last recommendation for the ENV: PSDrive is to use the value from %COMPUTERNAME% instead of LocalHost. Yes, localhost will work in almost all cases, but if you are capturing output you have no way of knowing what computer the command actually run on. Using $env:computername will always return an actual computername, so why not use it? So if you are defining a function parameter and want to default to localhost, set the default to the actual computer name:

Param( [string]$Computername = $env:computername)

So, to see what environmental variables you have, get a directory listing of ENV: and to reference a variable, use the item path preceded by a $ sign.

About the Author

Jeffery Hicks is an IT veteran with over 25 years of experience, much of it spent as an IT infrastructure consultant specializing in Microsoft server technologies with an emphasis in automation and efficiency. He is a multi-year recipient of the Microsoft MVP Award in Windows PowerShell. He works today as an independent author, trainer and consultant. Jeff has written for numerous online sites and print publications, is a contributing editor at Petri.com, and a frequent speaker at technology conferences and user groups.

comments powered by Disqus
Most   Popular