Environment Variables

I. Introduction

In this chapter, we will study the concept of environment variables in Windows, and we will see how to manipulate these environment variables using some PowerShell commands.

Unlike variables declared in a script or during a PowerShell session, environment variables are stored at the system level. Before moving on to practice, I suggest a reminder about the concept of environment variables.

II. What is an Environment Variable?

An environment variable is a dynamic and global variable within an operating system. The different processes on the machine can access these variables to obtain information about the current system configuration, in this case Windows in our example. Other systems like Linux and macOS also use environment variables. In other words, an environment variable is not directly linked to PowerShell.

On Windows, we find several dozen environment variables, including these very useful ones:

  • ComputerName: name of the computer
  • LogonServer: server used to authenticate the current session, usually an Active Directory domain controller in a business environment, or the local host if it's a local session
  • SystemDrive: drive letter where Windows is installed, usually “C:”
  • Username: name of the user currently logged on to the machine
  • UserProfile: path to the user's Windows profile
  • UserDnsDomain: the full name (DNS name) when connecting to a domain
  • UserDomain: the short name of the Active Directory domain
  • Processor_Architecture: processor architecture, for example AMD64

These environment variables are widely used by the operating system, as well as by software installed on your machine, and they are also very useful in scripts. The computer name can be retrieved via the environment variable “ComputerName”, which is very convenient because the value will adapt from one machine to another, making the script more versatile.

When I say these variables are dynamic, it means that the value can change over time, depending on the computer's hardware configuration, but also its settings and even the user logged on to the computer.

For example, if I log in with the user “florian” on my PC, the environment variable “Username” will have the value “florian”. Then, if I log in with the user “it-connect”, the variable “Username” will take the value “it-connect”, etc.

III. Listing Environment Variables with PowerShell

Open a PowerShell or Windows PowerShell console, as we will start manipulating. To list all environment variables, we need to query the environment variable drive: “Env:”. As we would do to list the contents of a folder, we will use the command “Get-ChildItem”, which gives:

Get-ChildItem Env:

As you can see in the image below, all environment variables are displayed. We have the name and value of each variable.

Get-ChildItem Env:
Get-ChildItem Env:

With the alias of “Get-ChildItem”, it also works and it's shorter:

gci env:

If we want to display the value of a specific variable, we can specify its name after “env:”, like this:

gci env:computername

For example, the environment variable “PSModulePath” gives us the paths to the different directories where PowerShell looks to load its modules.

gci env:psmodulepath

This returns:

C:\Users\florian\Documents\WindowsPowerShell\Modules;C:\Program Files\WindowsPowerShell\Modules;C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules

This output is not very readable because all paths are on the same line. To specify one path per line, we can split the string by targeting the character “;” with the method “Split()”, like this:

($env:PSModulePath).split(“;”)

IV. Using an Environment Variable in a PowerShell Script

Historically, when using the Command Prompt and MS-DOS commands, to access an environment variable, it was sufficient to enclose its name with the “%” symbol. For example:

%COMPUTERNAME%

However, “in PowerShell this syntax doesn't work; the” writing is different. To use an environment variable to retrieve its value, we will use this syntax:

$env:<variable name>

For example, to get the computer name by reading the “COMPUTERNAME” environment variable:

$env:COMPUTERNAME

When executing this command, PowerShell will read the content of the environment variable and display it in the console. The computer name will be returned.

COMPUTERNAME Environment Variable in PowerShell
COMPUTERNAME Environment Variable in PowerShell

This way, we can use any environment variable in a PowerShell script. For example, to display your computer name, execute:

Write-Host “My computer name is $env:computername

There's a variable that is widely used, especially by software, it's the “USERPROFILE” variable because it allows obtaining the path of the current user's profile. To display it, the principle is the same as the previous variable:

$env:USERPROFILE

I also take this opportunity to point out that you can write variable names in uppercase or lowercase, it doesn't matter.

V. Modifying an Environment Variable with PowerShell

It's possible to modify a variable temporarily, for the duration of a script for example. For this, we can use “Set-Item” to modify the variable. For example, to add the “C:PS_MODULES” directory to the “PSModulePath” variable, we will use this command:

Set-Item -Path Env:PSModulePath -Value ($Env:PSModulePath + “;&C:PS_MODULES”)

The “;” character before the path name is important to act as a separator between the value we're adding and the previous value. Using “($Env:PSModulePath +”;C:PS_MODULES “)” allows us to retain the current values and add our value.

Here's another syntax to add our additional path:

$env:psmodulepath += “;C:PS_MODULES”

If we want the “PSModulePath” variable to contain only the “C:PS_MODULES” folder, we should do:

Set-Item -Path Env:PSModulePath -Value “C:PS_MODULES

All of this is only temporary and applies to the current PowerShell session. If you close the console and reopen it, your modification will be lost!

Note: to create a temporary environment variable, we will use the command: New-Item -Path Env:itconnect -Value “www.it-connect.fr”. The previous command allows creating a variable named “itconnect” with the value “www.it-connect.fr”.

To persistently modify an environment variable, you need to use the .NET class "[System .Environment]" according to the documentation. However, this method doesn't work every time... Unfortunately. The modification is also made temporarily.

Here's a command to add the “C:PS_MODULES” path to the “PATH” environment variable.

[System .Environment]::SetEnvironmentVariable(“Path”,$Env:Path + “;C:PS_MODULES”)

If you know a reliable method to modify an environment variable persistently, I'm interested. Otherwise, the best method remains modification via the graphical interface.