Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update Windows PowerShell session environment variables from registry?

Tags:

powershell

This could be a simple question, but I couldn't find a proper answer.

How do you update the environment variables from within a current Windows PowerShell session without closing the current one?

Up to now, when I modify for example the PATH environment variable from Control Panel > System, I have to close current session and open a new one, so that variables are refreshed, or issue a SetEnviromentVariable which is cumbersome.

I'm coming from the Linux world, so I'm looking for something like source command.

like image 789
Pablo Burgos Avatar asked Jan 17 '13 14:01

Pablo Burgos


People also ask

How do you update an environment variable in PowerShell?

To set the environmental variable using PowerShell you need to use the assignment operator (=). If the variable already exists then you can use the += operator to append the value, otherwise, a new environment variable will be created.

Where are PowerShell environment variables stored?

In PowerShell, environment variables are stored in the Env: "drive", accessible through the PowerShell environment provider, a subsystem of PowerShell. This isn't a physical drive, but a virtual file system. Environment variables convey information about your login session to your computer.


2 Answers

There's no need to go dumpster diving in the registry for this stuff:

foreach($level in "Machine","User") {    [Environment]::GetEnvironmentVariables($level) } 

If you want to make PATH variables work right, you'd have to treat them specially (that is, concatenate the (potentially) new stuff to what you already have, and not lose anything, because you can't tell for sure what you should remove).

foreach($level in "Machine","User") {    [Environment]::GetEnvironmentVariables($level).GetEnumerator() | % {       # For Path variables, append the new values, if they're not already in there       if($_.Name -match 'Path$') {           $_.Value = ($((Get-Content "Env:$($_.Name)") + ";$($_.Value)") -split ';' | Select -unique) -join ';'       }       $_    } | Set-Content -Path { "Env:$($_.Name)" } } 

Notice that Set-Content actually sets the variables in your process environment, the same as doing something like $env:Temp = Convert-Path ~\AppData\Local\Temp

like image 83
Jaykul Avatar answered Sep 24 '22 17:09

Jaykul


The environment gets populated on process start-up which is why you'll need to restart the process.

You can update the environment by reading it from the registry. Maybe with a script like the following:

function Update-Environment {     $locations = 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment',                  'HKCU:\Environment'      $locations | ForEach-Object {         $k = Get-Item $_         $k.GetValueNames() | ForEach-Object {             $name  = $_             $value = $k.GetValue($_)              if ($userLocation -and $name -ieq 'PATH') {                 Env:\Path += ";$value"             } else {                 Set-Item -Path Env:\$name -Value $value             }         }          $userLocation = $true     } } 

(untested)

like image 21
Joey Avatar answered Sep 25 '22 17:09

Joey