Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Open regedit.exe, navigate to HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment. Create two environment variables:

Name   Type            Data
-----  --------------  -----------
zbar   REG_SZ          water
zfoo   REG_EXPAND_SZ   %zbar%

Open new cmd.exe, powershell.exe or whatever. These variables are missing. Make LogOff, then LogOn. In cmd.exe window type echo %zbar% - water is displayed. Type echo %zfro%..... %zbar% is displayed, but I expect to see expanded value - water.

And now. Open Windows Environment Variables dialog. Alter or create any variable (for example zzz=zzz). Reopen cmd.exe and type echo %zfro% - now you see water!

Actually, I am creating these variables with PowerShell script. But all this script does is described registry manipulations.


  1. How to force zfoo variable to have a correct value without that magic with opening Windows Environment Variables dialog and altering some variables? Maybe I should call some API, something like [Microsoft.Win32.Registry]::Refresh()?
  2. It is possible to make these variables visible to users without need for LogOff/LogOn operations? If I edit user-level environment variables (also in registry) they are immediately available, but with global - they are not.


share|improve this question
up vote 8 down vote accepted

You need to broadcast the WM_SETTINGCHANGE Message.

Remember: You're not actually setting any environment variables of any form when you modify the registry. Environment variables are part of each individual process' memory space, with each process having its own set. They don't live in the registry. You are changing a template. You need to persuade the programs that set actual environment variables to re-read the template and set their environments accordingly. You do that by broadcasting a Windows message that tells any interested parties that the template in the registry has changed. Microsoft Windows Explorer is one such interested party, and modifies its own environment variables whenever it hears that the template has changed. These modifications are then inherited in the normal way by any new process that Explorer spawns.

share|improve this answer
Thanks. That helped. – Roman Feb 28 '11 at 12:04
Yes, you need to broadcast WM_SETTINGCHANGE (though only windows that specifically handle it will actually pick up the changes), but also, note that even then, when you make a(ny) change, any variables that contain other variables will stop getting expanded until you reboot (including ones that already existed). It’s a weird bug (in at least XP and 7) that I’ve banged my head against countless times. – Synetech May 25 '11 at 1:22

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.