Echo %PATH%
returns system PATH variable + user PATH variable.
How to get only the user PATH variable?
The system PATH
variable is stored in Windows registry with value Path
of type REG_EXPAND_SZ
containing references to environment variables like %SystemRoot%
or if not correct modified by an application of type REG_SZ
without environment variable references under the registry key:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment
The user PATH
variable does not exist by default in Windows registry. It is stored in Windows registry with value Path
of type REG_EXPAND_SZ
or REG_SZ
once created by an application or manually by the user under the registry key:
HKEY_CURRENT_USER\Environment
The external command REG with command QUERY
can be used to read the value of the system or the user PATH
variable directly from Windows registry with standard user permissions.
It is possible to read the user PATH
variable from Windows registry and assign its value to an environment variable UserPath
with additionally expanding all environment variables in directory paths list.
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "UserPath="
for /F "skip=2 tokens=1,2*" %%G in ('%SystemRoot%\System32\reg.exe query "HKCU\Environment" /v "Path" 2^>nul') do if /I "%%G" == "Path" (
if /I "%%H" == "REG_EXPAND_SZ" (call set "UserPath=%%I") else if /I "%%H" == "REG_SZ" set "UserPath=%%I"
if defined UserPath goto UserPathRead
)
echo User PATH is not defined or has no string value.
goto EndBatch
:UserPathRead
setlocal EnableDelayedExpansion
echo The user PATH is: !UserPath!
endlocal
:EndBatch
echo/
pause
endlocal
The output format of reg query
depends on version of Windows which makes the additional case-insensitive IF condition necessary. For details on reg query
output format see for example Reading NT's Registry with REG Query written by Rob van der Woude.
Example output of reg query HKCU\Environment /v Path
on Windows XP:
! REG.EXE VERSION 3.0
HKEY_CURRENT_USER\Environment
Path REG_SZ C:\BatUtils
There is an empty line at beginning and one more at end of the output as well as a header line and one more empty line above the line with the registry key.
The line with the data of interest starts with four space characters and has next the case-insensitive name of the registry value Path
. Then a single horizontal tab character is output left to the registry value type REG_SZ
. Last there is one more horizontal tab character before the string value of Path
is output which could contain also one or more space characters.
Example output of reg query HKCU\Environment /v Path
on Windows Vista or newer Windows versions:
HKEY_CURRENT_USER\Environment
Path REG_SZ C:\BatUtils
There is also an empty line at beginning and one more at end of the output. But there is no header. The second line contains already the registry key.
The line with the data of interest starts with four space characters and has next the case-insensitive name of the registry value Path
. Then four spaces instead of a tab are output left to the registry value type REG_SZ
. Last there are again four spaces instead of a tab before the string value of Path
is output which could contain also one or more space characters.
The command REG is executed in a separate command process in background by FOR. The error message output by REG to handle STDERR in case of registry key HKCU\Environment
or value Path
do not exist is suppressed by redirecting it to device NUL with 2>nul
. The redirection operator >
must be escaped here with caret character ^
to be interpreted as literal character on parsing FOR command line by Windows command interpreter, but as redirection operator on later execution of REG command line in separate background command process.
The FOR options defined with "skip=2 tokens=1,2*"
result in skipping the first two lines of REG output and splitting the other lines up into three substrings (tokens) using the default delimiters space and tab.
The first space/tab delimited string is assigned to first loop variable G
which is the name of the variable on reaching the line with the data of interest.
The second substring being the registry value type is assigned to loop variable H
being the next character in ASCII table. This behavior is the reason why FOR loop variables are case-sensitive.
Everything after spaces/tabs after second substring is assigned to loop variable I
without splitting up the rest of the line because of *
in options string after tokens=1,2
.
So on Windows Vista and later Windows versions the command FOR processes as first line from output of REG the line with Path
while on Windows XP the first line processed is the line with the registry key which is the reason why the first IF condition is necessary.
The second IF condition makes a case-insensitive string comparison to find out the type of the registry value with name Path
. The string assigned to Path
contains on type REG_EXPAND_SZ
one or more environment variable references. For that reason the command call
is used which results in parsing the string value read from the registry and assigned to the loop variable I
by the Windows command processor to expand all environment variable references before command SET is executed to assign the expanded string value to environment variable UserPath
.
Note: cmd.exe
searches for an executable or script with name set
using the local environment variables PATHEXT
and PATH
because of the usage of command CALL. The command CALL is designed for calling a batch file from within a batch file and not to force the Windows command processor to parse a command line a second time.
The third IF condition is executed only if the registry value Path
is not of type REG_EXPAND_SZ
. It compares case-insensitive the registry value type against the string REG_SZ
in which case the string value of Path
can be assigned directly to the environment variable UserPath
.
The environment variable UserPath
is explicitly undefined above the FOR loop. So if the current line has as first string Path
in any case and the registry value type is REG_EXPAND_SZ
or REG_SZ
, there should be now defined the environment variable UserPath
as otherwise there is either a registry value Path
with wrong type or with an empty string. It is possible to have Path
stored in Windows registry with an empty string, but it is not possible to define the environment variable UserPath
with an empty string.
The fourth IF condition verifies that the environment variable UserPath
is really defined with a non-empty string. In this case the command GOTO is used to exit the FOR loop on having successfully read the user PATH
variable from Windows registry by jumping to the command block for further processing the environment variable UserPath
.
The command block below the FOR loop is reached if the user PATH
variable does not exist at all in Windows registry, or is of wrong type, or exists with an empty string.
For completeness a batch code to
PATH
from Windows registry without expansion,PATH
variables to PATH
with overwriting local PATH
in current command process in current environment,;;
by ;
in PATH
value and;
from end of PATH
value if there is one.This batch code does not check if user PATH
contains one or more directory paths being already present in system PATH
before concatenating them. So it is possible that a directory path is in local PATH
finally present more than once.
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem Get directly from Windows registry the system PATH variable value.
set "PathExpand="
set "PathSystem="
for /F "skip=2 tokens=1,2*" %%G in ('%SystemRoot%\System32\reg.exe query "HKLM\System\CurrentControlSet\Control\Session Manager\Environment" /v "Path" 2^>nul') do if /I "%%G" == "Path" (
if /I "%%H" == "REG_EXPAND_SZ" (set "PathExpand=1" & set "PathSystem=%%I") else if /I "%%H" == "REG_SZ" set "PathSystem=%%I"
if defined PathSystem goto GetUserPath
)
rem Get directly from Windows registry the user PATH variable value.
:GetUserPath
set "PathUser="
for /F "skip=2 tokens=1,2*" %%G in ('%SystemRoot%\System32\reg.exe query "HKCU\Environment" /v "Path" 2^>nul') do if /I "%%G" == "Path" (
if /I "%%H" == "REG_EXPAND_SZ" (set "PathExpand=1" & set "PathUser=%%I") else if /I "%%H" == "REG_SZ" set "PathUser=%%I"
if defined PathUser goto SetPath
)
rem Concatenate the two PATH values to a single value.
rem Expand the environment variable references if that is necessary at all.
rem Next replace all two consecutive semicolons by a single semicolon.
rem Last remove semicolon from end of the directories list if there is one.
:SetPath
set "PATH=%PathSystem%;%PathUser%"
if defined PathExpand call set "PATH=%PATH%"
set "PATH=%PATH:;;=;%"
if "%PATH:~-1%" == ";" set "PATH=%PATH:~0,-1%"
rem Output the environment variables PATH and PATHEXT and all other
rem environment variables starting case-insensitive with the string
rem Path as used in this batch file code to see what happened here.
set PATH
endlocal
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
echo /?
endlocal /?
for /?
goto /?
if /?
pause /?
reg /?
reg query /?
rem /?
set /?
setlocal /?
Read also the Microsoft article about Using Command Redirection Operators for an explanation of 2>nul
and the answer on Stack Overflow topic Single line with multiple commands using Windows batch file for meaning of operator &
on a command line.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With