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.
rem Add c:\bin to the path
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.
set PATHKEY=HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
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.
REG QUERY "%PATHKEY%" /v "%PATHVAR%" >"%TMPFILE%" 2>nul:
if errorlevel 1 goto :newpath
rem REG QUERY outputs several lines. We only care about the last non-blank line
rem Fortunately, a 'for' loop ignores blank lines.
for /f "delims=" %%i in (%TMPFILE%) do set XLINE=%%i
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 See below for other ways we can extract the path value from XLINE.
for /f "tokens=1,2,* delims= " %%i in ("!XLINE!") do set VARNAME=%%i & set VARTYPE=%%j & set XVALUE=%%k
rem Append an element to the Path.
rem Update the path
REG ADD "%PATHKEY%" /v "%PATHVAR%" /t REG_EXPAND_SZ /d "!NEWPATH!" /f
rem The Path variable does not exist and so create it
REG ADD "%PATHKEY%" /v "%PATHVAR%" /t REG_EXPAND_SZ /d "!ADDPATH!"
rem Delete the temporary file.
rem Here are some variations for parsing XLINE to extract the value.
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 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 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 The code still has a flaw in that it will fail if the variable name
rem contains four consecutive spaces.
set XLINE=!XLINE: =^|!
for /f "tokens=1,2,* delims=|" %%i in ("!XLINE!") do set VARNAME=%%i & set VARTYPE=%%j & set XVALUE=%%k