Everything you need to know about viewing, creating, editing, and managing system and user environment variables — from the GUI to PowerShell.
Environment variables are named key-value pairs stored by the operating system that hold configuration information used by programs, scripts, and the shell itself. Think of them as a global settings registry that any running process can read — without hardcoding paths or values directly into code.
For example, the well-known PATH variable tells Windows where to look when you type a command into Command Prompt. Instead of typing C:\Windows\System32\notepad.exe every time, you just type notepad — because C:\Windows\System32 is already listed in PATH.
Environment variables have been a core part of Windows since NT 3.1, and their behavior is essentially identical across Windows 10 and Windows 11. The GUI dialogs look slightly different due to the Windows 11 design refresh, but the underlying registry locations, inheritance rules, and command-line tools work exactly the same way.
Developers, system administrators, and power users rely on environment variables for a wide range of tasks. They allow you to store sensitive data like API keys outside of source code, configure runtime behavior of applications without recompiling, create portable scripts that work on any machine, and define installation paths for tools like Python, Java, Node.js, and Git.
Windows recognizes four distinct scopes for environment variables. Understanding scope is critical, because a variable defined at one level may override, be overridden by, or simply be invisible to another level.
Defined per user account. Stored in HKCU\Environment in the registry. Only available to processes running under that user. Take precedence over Machine variables with the same name (except PATH).
Apply to all users on the machine. Stored in HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment. Require Administrator rights to modify.
Exist only for the duration of a single process and its children. Set via set in CMD or $env: in PowerShell. Changes are discarded when the process ends.
A special subset stored in HKCU\Volatile Environment. Created fresh at each logon (e.g., SESSIONNAME, LOGONSERVER). Lost on logoff and not user-editable.
For most variables, User variables take precedence over System variables when both exist with the same name. The one important exception is PATH: Windows concatenates the System PATH and User PATH together (System first, then User), so both contribute to the final value seen by any running process.
There are several ways to open the Environment Variables dialog. Here are the most reliable methods, all of which work on both Windows 10 and Windows 11:
Win + R, type sysdm.cpl, and press Enter.Win + S to open Search.Win + R to open the Run dialog.rundll32 sysdm.cpl,EditEnvironmentVariables and press Enter.rundll32 sysdm.cpl,EditEnvironmentVariables as a desktop shortcut if you edit environment variables often. It's the fastest one-click route to the dialog on any Windows 10/11 system.
The command line gives you fast, scriptable access to environment variable values without opening any GUI dialogs.
CMD — list all variablesset
CMD — print a single variableecho %VARIABLE_NAME%
echo %PATH%
echo %USERNAME%
CMD — filter variables by prefixset APP_
Typing set with no arguments dumps every environment variable available in the current process. Typing set PREFIX (no equals sign) lists every variable whose name starts with that prefix — useful for quickly checking all JAVA_ or PYTHON related variables.
PowerShell — list all variablesGet-ChildItem Env:
PowerShell — read a single variable$env:PATH
$env:USERNAME
$env:APPDATA
PowerShell — filter and formatGet-ChildItem Env: | Where-Object { $_.Name -like "APP_*" }
Get-ChildItem Env: | Sort-Object Name | Format-Table -AutoSize
PowerShell — read persistent User variable from registry[System.Environment]::GetEnvironmentVariable("VARIABLE_NAME", "User")
[System.Environment]::GetEnvironmentVariable("VARIABLE_NAME", "Machine")
MY_APP_ROOT) and the Variable value (e.g., C:\MyApp).CMD — set a variable for the current sessionset MY_VARIABLE=HelloWorld
set APP_ENV=production
CMD — delete a variable from the current sessionset MY_VARIABLE=
CMD — create a persistent User variablesetx MY_VARIABLE "HelloWorld"
CMD — create a persistent System variable (requires Admin)setx MY_VARIABLE "HelloWorld" /M
setx writes to the registry and affects future processes, but does not update the current CMD session's environment. You must open a new CMD window to see the new value. Also note that setx silently truncates values longer than 1,024 characters — a common pitfall when appending to PATH.
The PATH variable is by far the most important and most frequently modified environment variable. It is a semicolon-delimited list of directories that Windows searches, in order, when you run an executable without specifying its full path.
Windows 10 and 11 include a dedicated PATH editor that displays each entry on its own line, making it far easier to manage than manually editing the raw semicolon-separated string.
Path in either the User or System section.PowerShell — append to User PATH permanently$current = [System.Environment]::GetEnvironmentVariable("Path", "User")
$newEntry = "C:\MyTool\bin"
[System.Environment]::SetEnvironmentVariable("Path", "$current;$newEntry", "User")
PowerShell — append to System PATH (run as Administrator)$current = [System.Environment]::GetEnvironmentVariable("Path", "Machine")
$newEntry = "C:\MyTool\bin"
[System.Environment]::SetEnvironmentVariable("Path", "$current;$newEntry", "Machine")
PowerShell's [System.Environment] .NET class and the Env: provider give you full, scriptable control over all scopes of environment variables.
PowerShell — set a persistent User variable[System.Environment]::SetEnvironmentVariable("API_KEY", "abc123xyz", "User")
PowerShell — set a persistent System variable (Admin required)[System.Environment]::SetEnvironmentVariable("DB_HOST", "prod-db-01", "Machine")
PowerShell — delete a User variable[System.Environment]::SetEnvironmentVariable("API_KEY", $null, "User")
PowerShell — set variable for current session only$env:MY_TEMP_VAR = "temporary_value"
Remove-Item Env:MY_TEMP_VAR
PowerShell — export all User variables to a fileGet-ChildItem Env: | Export-Csv -Path "$HOME\env_backup.csv" -NoTypeInformation
PowerShell — import variables from a .env file (common pattern)Get-Content ".env" | ForEach-Object {
if ($_ -match "^([^#=]+)=(.*)$") {
[System.Environment]::SetEnvironmentVariable($matches[1].Trim(), $matches[2].Trim(), "User")
}
}
WM_SETTINGCHANGE message so Explorer and new terminal windows pick up changes without a full logoff. This technique is used by many installers (like Chocolatey and scoop).
Windows ships with a rich set of pre-defined environment variables. Knowing them saves time and makes scripts portable across different machines and users.
| Variable | Typical Value | Description |
|---|---|---|
%USERNAME% |
john.doe |
The currently logged-in user's account name. |
%USERPROFILE% |
C:\Users\john.doe |
Full path to the current user's home folder. |
%APPDATA% |
C:\Users\john.doe\AppData\Roaming |
Roaming application data folder for the current user. |
%LOCALAPPDATA% |
C:\Users\john.doe\AppData\Local |
Local (non-roaming) application data folder. |
%TEMP% / %TMP% |
C:\Users\john.doe\AppData\Local\Temp |
Temporary files directory. Safe to clean periodically. |
%SYSTEMROOT% |
C:\Windows |
Root directory of the Windows installation. |
%SYSTEMDRIVE% |
C: |
Drive letter of the system drive. |
%WINDIR% |
C:\Windows |
Alias for %SYSTEMROOT%. Used by older applications. |
%PROGRAMFILES% |
C:\Program Files |
Default installation folder for 64-bit programs. |
%PROGRAMFILES(X86)% |
C:\Program Files (x86) |
Default installation folder for 32-bit programs on 64-bit Windows. |
%COMPUTERNAME% |
DESKTOP-ABC123 |
The machine's NetBIOS name. |
%OS% |
Windows_NT |
Always Windows_NT on modern Windows. Used in legacy batch scripts for OS detection. |
%PROCESSOR_ARCHITECTURE% |
AMD64 |
CPU architecture of the current process (AMD64, x86, ARM64). |
%PATH% |
(merged list) | Semicolon-separated list of directories searched for executables. |
%PATHEXT% |
.COM;.EXE;.BAT;… |
File extensions Windows considers executable when searching PATH. |
%PUBLIC% |
C:\Users\Public |
Shared public folder accessible by all users on the machine. |
You can use any of these variables in File Explorer's address bar, the Run dialog (Win+R), batch scripts, and PowerShell by wrapping them in percent signs (%VARIABLE%) or the $env:VARIABLE syntax.
Changes aren't taking effect in open applications. Environment variable changes are only read when a process starts. You must close and reopen the application, terminal, or IDE. Signing out and back in ensures all processes get the updated values.
Command not found after adding to PATH. First verify the path was added correctly with echo %PATH% in a new CMD window. Check for typos, missing backslashes, or extra spaces. Ensure you edited the correct scope (User vs. System).
PATH appears truncated — entries are missing. This is caused by the 1,024-character limit of the old setx command or legacy registry tools. Use the GUI PATH editor or the PowerShell [System.Environment] method, which supports paths up to 32,767 characters (the Windows registry limit).
System variables not visible to the current user. Make sure you're looking in both the User and System sections of the Environment Variables dialog, or use set in CMD, which shows the merged result. If a System variable still doesn't appear, check Group Policy — it can override or hide variables.
An application ignores the environment variable. Some applications cache environment variables at startup and don't re-read them while running. Restart the application. Some also require the variable to be set before the service that launches them starts — in that case, a system reboot may be necessary.
set > "%USERPROFILE%\Desktop\env_backup.txt" in CMD. This gives you a reference to restore from if something breaks.
PATH, which is concatenated from both. If you're the only user and have admin rights, there's little practical difference; for shared machines or controlled environments, System variables are the right choice for machine-wide settings.
Path under User variables, click Edit, then click New and paste the directory (e.g., C:\Python312 and C:\Python312\Scripts for Python, or C:\Program Files\nodejs for Node.js). Open a new CMD window and type python --version or node --version to confirm.
C:\Program Files\...). When you reference such a variable in CMD, wrap the expansion in quotes: "%MY_PATH%". Variable names should be alphanumeric with underscores — avoid spaces and special characters in names. Do not include literal quotes inside a variable's value using the GUI; they will be stored verbatim and may cause unexpected behavior when scripts expand the variable.
%PATH%, %path%, and %Path% all refer to the same variable. This is different from Linux/macOS, where PATH and path would be two distinct variables. By convention, Windows environment variable names are written in ALL_CAPS, but this is purely stylistic.
MYAPP_API_KEY. Be aware that environment variables are stored in plaintext in the Windows registry — they are not encrypted. Any process running under your user account can read them. For higher security, consider Windows Credential Manager, Azure Key Vault, or tools like direnv combined with .env files excluded from version control. Never commit environment variables containing secrets to source code repositories.
REG_EXPAND_SZ (the type used for expandable environment variables like PATH). However, the legacy setx command silently truncates values longer than 1,024 characters — a known limitation. To safely manage long values (especially PATH), always use the GUI editor or [System.Environment]::SetEnvironmentVariable() in PowerShell, which communicate directly with the registry without this restriction.
Environment variables are a foundational part of Windows configuration — mastering them makes you significantly more productive as a developer, sysadmin, or power user. Use the GUI editor for safe, visual PATH management; use PowerShell's [System.Environment] API for scriptable, scope-aware automation without character limits; and use set/$env: for temporary, session-scoped values that don't pollute the system registry.
Whether you're on Windows 10 or Windows 11, the underlying mechanisms are identical — only the visual chrome differs. Once you understand User vs. System scope, the PATH merging behavior, and how process inheritance works, you'll rarely run into issues you can't diagnose and fix in minutes.