216

I need to access an environment variable remotely. To do this, I think the best way is to read it from registry.

Where are environment variables stored in the Windows Registry?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Brian R. Bondy
  • 339,232
  • 124
  • 596
  • 636

4 Answers4

316

Here's where they're stored on Windows XP through Windows Server 2012 R2:

User Variables

HKEY_CURRENT_USER\Environment

System Variables

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Steve Scheffler
  • 3,706
  • 2
  • 21
  • 22
  • 7
    Remember to restart your system in order to put your changes into effect. – 0x6B6F77616C74 Aug 06 '12 at 13:57
  • 26
    You don't need to restart. Just kill Explorer.exe and bring it back alive. It's the parent process for e.g. cmd.exe (when started from the Start menu) – Cristian Diaconescu Dec 08 '12 at 01:04
  • 2
    How about for other processes - like IIS? I'm guessing Explorer.exe isn't the parent for those, so a restart would be needed? – Colin Jan 09 '13 at 20:25
  • 3
    Processes read in system env variables at the time they start. So with something like IIS, restarting that service should bring in the updated values. – Steve Scheffler Jan 10 '13 at 03:11
  • 12
    User path variables (My Documents, AppData, etc) are stored at `HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders` – mythofechelon Jul 31 '13 at 20:21
  • 2
    @0x6B6F77616C74: Log off is as far as you need to go for applying any env var changes. – Violet Giraffe Sep 28 '13 at 15:07
  • 3
    Windows 7 uses the same registry locations. – quintessential5 Jun 02 '14 at 16:06
  • 1
    @CristiDiaconescu & 0x6B6F77616C74, it's worth to mention that if you were doing only local changes, then you should avoid restarting explorer.exe or the whole system. Instead you should use the corresponding control panel applet, or if you are doing it programatically, broadcast the `WM_SETTINGCHANGE` message with `lParam` set to the string `Environment`. Important part of this process is that notification (which does that control panel applet, or your application after you modify those registry values). – TLama Sep 26 '14 at 09:57
  • Is there a possibility to read the `environment variables` from different users? I think `HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders` only contains the variables of the currently logged in user? – gies0r Nov 03 '15 at 13:59
  • 2
    @gies0r Sure - you would just go to `HKEY_USERS\The-other-users-SID\...` or wherever. When you look at `HKEY_CURRENT_USER` you're looking at an alias for that key for _your_ SID. Permissions might get in your way, though. Hint: The first user created on your machine probably has the SID that ends in -1001; -1000 is for the built-in Administrator account (which, these days, is disabled by default). The three big numbers before that are the "machine ID", which is generated randomly for each Windows install - or comes from your domain controller if you're in a domain. – Jamie Hanrahan Jun 21 '17 at 16:32
  • According to the docs running this should refresh the environment for the current shell: `RUNDLL32.EXE USER32.DLL,UpdatePerUserSystemParameters ,1 ,True` https://ss64.com/nt/reg.html – RecencyEffect Oct 23 '17 at 07:21
  • 1
    Might be worth mentioning that there's some environment variables located under `HKEY_CURRENT_USER\Volatile Environment` as well – solstice333 Apr 23 '18 at 10:10
  • Had an issue with ORACLE_HOME in registry. Setting it here, makes it work like charm. – Nigilan Jun 14 '18 at 06:18
23

There is a more efficient way of doing this in Windows 7. SETX is installed by default and supports connecting to other systems.

To modify a remote system's global environment variables, you would use

setx /m /s HOSTNAME-GOES-HERE VariableNameGoesHere VariableValueGoesHere

This does not require restarting Windows Explorer.

/M Specifies that the variable should be set in the system wide (HKEY_LOCAL_MACHINE) environment. The default is to set the variable under the HKEY_CURRENT_USER environment.

/S system Specifies the remote system to connect to.

Brian Burns
  • 20,575
  • 8
  • 83
  • 77
Jake Nelson
  • 1,748
  • 13
  • 22
  • 16
    Be careful with this, as setx truncates everything after the 1024 charachters!!! https://superuser.com/questions/387619/overcoming-the-1024-character-limit-with-setx – WalyKu Oct 24 '17 at 12:56
9

CMD:

reg query "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
reg query HKEY_CURRENT_USER\Environment

PowerShell:

Get-Item "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
Get-Item HKCU:\Environment

Powershell/.NET: (see EnvironmentVariableTarget Enum)

[System.Environment]::GetEnvironmentVariables([System.EnvironmentVariableTarget]::Machine)
[System.Environment]::GetEnvironmentVariables([System.EnvironmentVariableTarget]::User)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
masterxilo
  • 2,503
  • 1
  • 30
  • 35
2

I always had problems with that, and I made a getx.bat script:

:: getx %envvar% [\m]
:: Reads envvar from user environment variable and stores it in the getxvalue variable
:: with \m read system environment

@SETLOCAL EnableDelayedExpansion
@echo OFF

@set l_regpath="HKEY_CURRENT_USER\Environment"
@if "\m"=="%2" set l_regpath="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"

::REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v PATH /t REG_SZ /f /d "%PATH%"
::@REG QUERY %l_regpath% /v %1 /S

@FOR /F "tokens=*" %%A IN ('REG QUERY %l_regpath% /v %1 /S') DO (
@  set l_a=%%A
@    if NOT "!l_a!"=="!l_a:    =!" set l_line=!l_a!
)

:: Delimiter is four spaces. Change it to tab \t
@set l_line=!l_line!
@set l_line=%l_line:    =    %

@set getxvalue=

@FOR /F "tokens=3* delims=  " %%A IN ("%l_line%") DO (
@    set getxvalue=%%A
)
@set getxvalue=!getxvalue!
@echo %getxvalue% > getxfile.tmp.txt
@ENDLOCAL

:: We already used tab as a delimiter
@FOR /F "delims=    " %%A IN (getxfile.tmp.txt) DO (
    @set getxvalue=%%A
)
@del getxfile.tmp.txt

@echo ON
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Fantastory
  • 1,891
  • 21
  • 25