Setting Windows PowerShell environment variables
Tags: windows, powershell, metacall, tutorial
Published: 2022-03-02 05:57:19

Ever thought setting environment variables would be a simple automated task? Setting environment variables is an additional step in an operating system, which is required by certain software so it can work globally in our system.

Setting environment variables is a simple task in Windows, you can do it with PowerShell with a single line command.

```sh
# Current value of PATH environment variable

$env:PATH -split ';'

# Adding a new path to PATH

$env:PATH = $env:PATH + ';C:\bin'
```
Now, this will add **`C:\bin`** to PATH environment variable, but if you exit the PowerShell session and then re-run,

```sh
 $env:PATH -split ';'
```

The value **`C:\bin`** would have been removed automatically. 

Now you might ask, I want to make my changes permanent, so I don't have to set it every time I run PowerShell. Does PowerShell have a easier way to do this?

So, I was assigned a task in one of the Open-source project named [**MetaCall**](https://metacall.io), a super cool tool used for [Polyglot programming](https://en.m.wikipedia.org/wiki/Polyglot_(computing)), where I had to add a path to PATH variable permanently, so even if PowerShell session was over, the path value still stayed in PATH variable, basically to persist it. 

This is what I came up with after hours of debugging (as I was using PowerShell for the very first time). 

```sh
# Test folder
$InstallLocation = "C:\bin"
 
# To add folder to PATH
 $persistedPath = [Environment]::GetEnvironmentVariable('Path', [EnvironmentVariableTarget]::Machine) -split ';'
   if ($persistedPath -notcontains $InstallLocation) {
       $persistedPath = $persistedPath + $InstallLocation | where { $_ }
       [Environment]::SetEnvironmentVariable('Path', $persistedPath -join ';', [EnvironmentVariableTarget]::Machine)
     }
    
#To verify if PATH isn't already added
    $envPaths = $env:Path -split ';'
    if ($envPaths -notcontains $InstallLocation) {
        $envPaths = $envPaths + $InstallLocation | where { $_ }
        $env:Path = $envPaths -join ';'
    }
```

So, let's break this code down.

```sh
$InstallLocation = "C:\bin"
```
This is our test folder, which we would add in our PATH environment variable.

```sh
# To add folder to PATH
 $persistedPath = [Environment]::GetEnvironmentVariable('Path', [EnvironmentVariableTarget]::Machine) -split ';'
   if ($persistedPath -notcontains $InstallLocation) {
       $persistedPath = $persistedPath + $InstallLocation | where { $_ }
       [Environment]::SetEnvironmentVariable('Path', $persistedPath -join ';', [EnvironmentVariableTarget]::Machine)
     }
```
**`$persistedPath`** variable gets the value of the current environment variable and checks whether **`$InstallLocation`** is added to the path or not. If it's not added, it appends **`$InstallLocation`** to **`$persistedPath`**. This persists in the environment variable change for future sessions.

**`[EnvironmentVariableTarget]::Machine`** means the registry key is reserved for the environment variables associated with all users on the local machine.

```sh
#To verify if PATH isn't duplicated
    $envPaths = $env:Path -split ';'
    if ($envPaths -notcontains $InstallLocation) {
        $envPaths = $envPaths + $InstallLocation | where { $_ }
        $env:Path = $envPaths -join ';'
    }
```
Next up, this is really simple, it doesn't add another path to **`$env:Path`** if the same path already exists.

Check out [**MetaCall's repository**](https://github.com/metacall) and link to my [**PR**](https://github.com/metacall/install/pull/6), which shows how to implement this in actual codebase.

So, this was a simple script to set environment variables permanently through PowerShell. To learn more about PowerShell scripting refer to the [**official documentation**](https://docs.microsoft.com/en-us/powershell/scripting/overview?view=powershell-7.2) by Microsoft.

## Happy Scripting!! <\>