- Overview
- Notation used for variables
- Step 1: Scope and storage locations of environment variables
- Step 2: Viewing and setting environment variables in CMD (%VAR%)
- Step 3: How to verify user and system environment variables in CMD
- Step 4: Safe editing of PATH (warnings when using CMD)
- Step 5: Viewing and setting environment variables in PowerShell ($env:VAR)
- Step 6: Most accurate way to view user and system variables in PowerShell
- Step 7: Setting persistent variables with PowerShell (.NET API / recommended)
- Step 8: Safely editing the PATH variable (.NET API / strongly recommended)
- Step 9: Deleting environment variables
- Step 10: Applying and verifying changes
- Step 11: Bulk setting multiple environment variables (user and system)
- Summary
Overview
Windows environment variables are read from an environment block that is created when a process starts. This article explains in detail the scope of environment variables (process, user, system), how they are persisted, how to view and configure them using CMD and PowerShell, and clarifies exactly how user and system environment variables differ and how they are actually seen from each context.
Notation used for variables
| Variable | Example | Description |
|---|---|---|
<<VAR_NAME>> |
PATH |
Name of the environment variable to operate on |
<<VALUE>> |
C:\Tools |
Value to set |
Step 1: Scope and storage locations of environment variables
| Type | Storage location | Scope | Persistence | Notes |
|---|---|---|---|---|
| Process environment variables | Memory | Current process only | Temporary | CMD: set / PowerShell: $env: |
| User environment variables | HKCU\Environment |
Current user | Persistent | setx / .NET API |
| System environment variables (Machine) | HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment |
All users | Persistent | setx /M / .NET API (admin) |
Process, user, and system are separate layers
- Process environment variables: effective only in the current shell/process
- User environment variables: specific to the current user profile
- System environment variables: shared by all users
PATHoften appears as the concatenation of “system PATH + user PATH”
Because “what you see depends on where you look from”, you must decide the intended scope before setting any value.
Step 2: Viewing and setting environment variables in CMD (%VAR%)
2-1. List process environment variables
set
2-2. View a process environment variable
echo %<<VAR_NAME>>%
2-3. Temporarily set a process environment variable (current CMD only)
set <<VAR_NAME>>=<<VALUE>>
2-4. Set persistent environment variables with setx
Basic syntax
setx <<VAR_NAME>> "<<VALUE>>"
User scope (default)
setx <<VAR_NAME>> "<<VALUE>>"
System scope (/M required, administrator only)
setx <<VAR_NAME>> "<<VALUE>>" /M
Characteristics of
setx
- Does not update the current CMD session
- Values containing
%PATH%are expanded at runtime and stored as fixed text- Long
PATHvalues can be truncated (therefore not recommended for PATH)
Step 3: How to verify user and system environment variables in CMD
User environment variables (HKCU)
reg query HKCU\Environment
System environment variables (HKLM)
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
Using reg query lets you see the raw value per scope, so you can accurately check whether PATH is concatenated, overridden, or truncated.
Step 4: Safe editing of PATH (warnings when using CMD)
The following is a dangerous pattern and is not recommended:
# setx PATH "%PATH%;C:\Tools"
Reasons:
%PATH%is expanded and saved as a fixed string at that momentREG_EXPAND_SZmay be converted toREG_SZ, causing loss of%SystemRoot%and other placeholdersPATHmay be truncated if it is too long
For editing PATH, you should prefer PowerShell with the .NET API (see below) instead of setx.
Step 5: Viewing and setting environment variables in PowerShell ($env:VAR)
5-1. List process environment variables
Get-ChildItem Env:
5-2. View a process environment variable
$env:<<VAR_NAME>>
5-3. Temporarily set a process environment variable
$env:<<VAR_NAME>> = "<<VALUE>>"
Step 6: Most accurate way to view user and system variables in PowerShell
User environment variables (HKCU)
Get-ItemProperty "HKCU:\Environment"
System environment variables (HKLM)
Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"
Step 7: Setting persistent variables with PowerShell (.NET API / recommended)
User scope (User)
[System.Environment]::SetEnvironmentVariable("<<VAR_NAME>>","<<VALUE>>","User")
System scope (Machine, administrator)
[System.Environment]::SetEnvironmentVariable("<<VAR_NAME>>","<<VALUE>>","Machine")
Advantages of this method
- Prevents
PATHtruncation- Preserves
REG_EXPAND_SZwhere appropriate- Updates values in a safe and predictable way
Step 8: Safely editing the PATH variable (.NET API / strongly recommended)
$add = "C:\Tools"
$current = [System.Environment]::GetEnvironmentVariable("PATH","Machine")
$new = ($current.TrimEnd(';') + ';' + $add).Trim(';')
[System.Environment]::SetEnvironmentVariable("PATH",$new,"Machine")
Step 9: Deleting environment variables
9-1. Delete from the current PowerShell process only
Remove-Item Env:<<VAR_NAME>> -ErrorAction SilentlyContinue
9-2. Delete persistent values (remove from registry)
User
Remove-ItemProperty -Path "HKCU:\Environment" -Name "<<VAR_NAME>>" -ErrorAction SilentlyContinue
System (administrator)
Remove-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" -Name "<<VAR_NAME>>" -ErrorAction SilentlyContinue
Step 10: Applying and verifying changes
10-1. Check value in the current process
Get-ChildItem Env:<<VAR_NAME>>
10-2. Verify in CMD
echo %<<VAR_NAME>>%
10-3. Immediately load the persistent value into the current PowerShell session
$env:<<VAR_NAME>> = [System.Environment]::GetEnvironmentVariable("<<VAR_NAME>>","User")
Step 11: Bulk setting multiple environment variables (user and system)
# User environment
$vars = @{
"APPDATA_DIR" = "C:\AppData"
"LOG_PATH" = "C:\Logs"
"TOOLS" = "C:\Tools"
}
foreach ($v in $vars.GetEnumerator()) {
[System.Environment]::SetEnvironmentVariable($v.Key,$v.Value,"User")
}
# System environment (administrator)
$sysVars = @{
"JAVA_HOME" = "C:\Program Files\Java\<<VALUE>>"
}
foreach ($v in $sysVars.GetEnumerator()) {
[System.Environment]::SetEnvironmentVariable($v.Key,$v.Value,"Machine")
}
Summary
- Process, user, and system environment variables exist independently.
- CMD and PowerShell may show different scopes or combined values (especially for PATH).
- To see the true user and system values, inspect HKCU/HKLM directly.
setxcan persist values but has serious drawbacks for PATH and is not recommended for it.- The .NET API (
SetEnvironmentVariable) is the safest and most reliable way to manage environment variables.
