Fairly straightforward question. I need to update my PATH environment variable in Windows Server 2008 Core. Considering there's no GUI, how is this done from the command line?
To make persistent changes use
For example, to add a folder to the end of the current path, use:
SETX Path %Path%;C:\MyFolder
Your change won't be visible in the current
cmd.exe session, but it will be in all future ones.
SETX also allows setting system environment variables on remote systems.
Dealing with the Path variable is sticky as it is a combination of the system Path and user Path variables. The previous answers don't account for this. For example
SETX PATH %PATH%;C:\MyFolder
will set the user Path to the entire current system path, plus user path, and then append ';C:\MyFolder' to that. If I had used
SETX /M PATH %PATH%;C:\MyFolder then the system Path will get the current user Path added to it.
SETX /M is fine for any environment variable except the Path. Unfortunately, dealing with the Path variables is a pain as it involves updating registry and to be able to append a new value we must first copy the registry entry into an environment variable, append directory that we are adding to the path, and then write the results back into the registry.
There's another issue which is that the Path variables are stored as REG_EXPAND_SZ strings and it's common for a system path to contain references to
%SystemRoot%. This means whatever mechanism you use for reading, manipulating, and then writing the Path variable should ideally not expand anything.
Finally, it's common for there to be no user Path variable meaning the code that updates the Path needs to account for the error you will get if you try to read a variable that does not exist.
Here's some example code that can update the Path by updating the values in the registry.
@echo off setlocal ENABLEDELAYEDEXPANSION rem rem Add c:\bin to the path rem rem rem rem There are two values we can use for the PATHKEY. The one that starts rem with HKEY_LOCAL_MACHINE sets the path that's used by all processes and rem users on the system. The PATHKEY that starts with HKEY_CURRENT_USER rem updates the part of the Path that only visible to processes running rem under the current user account. rem set PATHKEY=HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment set PATHKEY=HKEY_CURRENT_USER\Environment set PATHVAR=Path set TMPFILE=%TEMP%\addpath.txt set ADDPATH=c:\bin rem rem Read the Path value from the registry into a file. I could have coded rem this with no temporary file by using: rem for /f "delims=" %%i in ('REG QUERY "%PATHKEY%" /v "%PATHVAR%" 2>nul:') do set XLINE=%%i rem However, having the temporary file was useful for debugging and as rem updating the path is something we don't often do we don't care if rem doing so is a bit slower. rem REG QUERY "%PATHKEY%" /v "%PATHVAR%" >"%TMPFILE%" 2>nul: if errorlevel 1 goto :newpath rem rem REG QUERY outputs several lines. We only care about the last non-blank line rem Fortunately, a 'for' loop ignores blank lines. rem for /f "delims=" %%i in (%TMPFILE%) do set XLINE=%%i rem rem Extract the value from the Path variable. Here's what we expect to see rem in XLINE though with with spaces shown as ~ symbols: rem rem ~~~~Path~~~~REG_EXPAND_SZ~~~~Path-is-here..." rem rem See below for other ways we can extract the path value from XLINE. rem for /f "tokens=1,2,* delims= " %%i in ("!XLINE!") do set VARNAME=%%i & set VARTYPE=%%j & set XVALUE=%%k rem rem Append an element to the Path. rem set NEWPATH=!XVALUE!;!ADDPATH! rem rem Update the path rem REG ADD "%PATHKEY%" /v "%PATHVAR%" /t REG_EXPAND_SZ /d "!NEWPATH!" /f goto :done rem rem The Path variable does not exist and so create it rem :newpath REG ADD "%PATHKEY%" /v "%PATHVAR%" /t REG_EXPAND_SZ /d "!ADDPATH!" goto :done rem rem Delete the temporary file. rem :done del "%TMPFILE%" endlocal goto :eof rem rem Here are some variations for parsing XLINE to extract the value. rem rem rem Quick and dirty method. It takes advantage of that REG QUERY returns a rem line with four spaces, the variable name which we know is four rem characters, four spaces, the variable type which we know is rem REG_EXPAND_SZ and is 13 characters, four spaces, and then the value. As rem some systems may be using REG_SZ Path strings the quick and dirty method rem seems like a bad idea. rem set XVALUE=!XLINE:~29! rem rem One flaw with the method I used in the code above is that you are rem allowed to have spaces in variable names. Here's a slight modification rem to the code to support spaces in variable names. It takes advantage of rem the fact that REG VIEW always puts four spaces each of the fields. We rem first translate instances of four spaces into vertical bars and use that rem character as the delimiter when parsing the line. rem rem I could have used any character as the delimiter as long as it's one rem that will not appear in the variable name, the variable type, or as the rem first character(s) of the variable's value. Some people use a tab here. rem I chose not to do that in this example as the tabs are not visible. rem rem The code still has a flaw in that it will fail if the variable name rem contains four consecutive spaces. rem set XLINE=!XLINE: =^|! for /f "tokens=1,2,* delims=|" %%i in ("!XLINE!") do set VARNAME=%%i & set VARTYPE=%%j & set XVALUE=%%k
If you want to set a path or other environment variable with spaces in it, I found it easier to use
regedit - which you can just start from the command prompt on Server Core.
The system wide environment variables are in
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment and the user ones are in
@user3347790's answer makes some valid points: a lot of the methods above are going to replace path with the expanded path (e.g.
%UserProfile% are going to be permanently expanded) and they are also going to combine machine and user paths into one. Based on that, adapting the code from that answer (if you need code) or just using
regedit (if you just want to make a few changes by hand) might be safer...