How do I set an env variable in PowerShell if it doesn't exist? How do I set an env variable in PowerShell if it doesn't exist? powershell powershell

How do I set an env variable in PowerShell if it doesn't exist?


The following code defines environment variable FOO, if it doesn't exist yet.

if (-not (Test-Path env:FOO)) { $env:FOO = 'bar' }

Note: This newly defined environment variable will only exist for the current process and any child processes it creates (e.g., when you start a new PowerShell session from the ISE). Thanks, PetSerAl.

The following was mostly contributed by Ansgar Wiechers, with a supplement by Mathias R. Jessen:

On Windows[*], if you want to define an environment variable persistently, you need to use the static SetEnvironmentVariable() method of the [System.Environment] class:

# user environment[Environment]::SetEnvironmentVariable('FOO', 'bar', 'User')# system environment (requires admin privileges)[Environment]::SetEnvironmentVariable('FOO', 'bar', 'Machine')

Note that these definitions take effect in future sessions (processes), so in order to define the variable for the current process as well, run $env:FOO = 'bar' in addition, which is effectively the same as [Environment]::SetEnvironmentVariable('FOO', 'bar', 'Process').

When using [Environment]::SetEnvironmentVariable() with User or Machine, a WM_SETTINGCHANGE message is sent to other applications to notify them of the change (though few applications react to such notifications).
This doesn't apply when targeting Process (or when assigning to $env:FOO), because no other applications (processes) can see the variable anyway.

See also.


[*] On Unix-like platforms, attempts to target persistent scopes User or Machine are quietly ignored, as of .NET (Core) 5, and this non-support for defining persistent environment variables is unlikely to change, given the lack of a unified mechanism across Unix platforms.


Code

function Set-LocalEnvironmentVariable {    param (        [Parameter()]        [System.String]        $Name,        [Parameter()]        [System.String]        $Value,        [Parameter()]        [Switch]        $Append    )    if($Append.IsPresent)    {        if(Test-Path "env:$Name")        {            $Value = (Get-Item "env:$Name").Value + $Value        }    }    Set-Item env:$Name -Value "$value" | Out-Null}function Set-PersistentEnvironmentVariable {    param (        [Parameter()]        [System.String]        $Name,            [Parameter()]        [System.String]        $Value,            [Parameter()]        [Switch]        $Append            )        Set-LocalEnvironmentVariable -Name $Name -Value $Value -Append:$Append    if ($Append.IsPresent) {        $value = (Get-Item "env:$Name").Value    }        if ($IsWindows) {        setx "$Name" "$Value" | Out-Null        return    }    $pattern = "\s*export[ \t]+$Name=[\w]*[ \t]*>[ \t]*\/dev\/null[ \t]*;[ \t]*#[ \t]*$Name\s*"        if ($IsLinux) {        $file = "~/.bash_profile"        $content = (Get-Content "$file" -ErrorAction Ignore -Raw) + [System.String]::Empty        $content = [System.Text.RegularExpressions.Regex]::Replace($content, $pattern, [String]::Empty);        $content += [System.Environment]::NewLine + [System.Environment]::NewLine + "export $Name=$Value > /dev/null ;  # $Name"        Set-Content "$file" -Value $content -Force        return    }    if ($IsMacOS) {        $file = "~/.zprofile"        $content = (Get-Content "$file" -ErrorAction Ignore -Raw) + [System.String]::Empty        $content = [System.Text.RegularExpressions.Regex]::Replace($content, $pattern, [String]::Empty);        $content += [System.Environment]::NewLine + [System.Environment]::NewLine + "export $Name=$Value > /dev/null ;  # $Name"        Set-Content "$file" -Value $content -Force        return    }    throw "Invalid platform."}

  • function Set-PersistentEnvironmentVariableSet a variable/value in actual process and system. This function calls Set-LocalEnvironmentVariable function to set process scope variables and perform task for set variables in machine scope.

On Windows you can use:

On Linux we can add export VARIABLE_NAME=Variable value to file ~/.bash_profile. For a new bash terminal the process execute these instructions located in ~/.bash_profile.

On MacOS similiar to Linux but if you have zsh terminal the file is .zprofile, if the default terminal is bash, the file is .bash_profile. In my function code we need to add detection of default terminal if you wish. I assume that default terminal is zsh.

  • function Set-LocalEnvironmentVariableSet a variable/value in actual process. Using Drive env:.

Examples

#Set "Jo" value to variable "NameX", this value is accesible in current process and subprocesses, this value is accessible in new opened terminal.Set-PersistentEnvironmentVariable -Name "NameX" -Value "Jo"; Write-Host $env:NameX#Append value "ma" to current value of variable "NameX", this value is accesible in current process and subprocesses, this value is accessible in new opened terminal.Set-PersistentEnvironmentVariable -Name "NameX" -Value "ma" -Append; Write-Host $env:NameX#Set ".JomaProfile" value to variable "ProfileX", this value is accesible in current process/subprocess.Set-LocalEnvironmentVariable "ProfileX" ".JomaProfile"; Write-Host $env:ProfileX

Output

Windows 10Windows

Ubuntu WSLUbuntu - Linux


References

Check About Environment Variables
Shell initialization files
ZSH: .zprofile, .zshrc, .zlogin - What goes where?