Blog / Coding tips

What Is %windir%? Windows Environment Variables Explained (With a List)

Cover image for What Is %windir%? Windows Environment Variables Explained (With a List)

%windir% is a Windows environment variable that holds the path of the Windows folder on the system drive, which is usually C:\Windows. The percent signs tell Windows to swap the name for its value, so typing %windir%\System32 in the Run box opens C:\Windows\System32. %SystemRoot% points to the same folder. Environment variables like these let scripts, installers and tutorials refer to folders without hard-coding a drive letter or user name.

I kept seeing %windir%, %appdata% and %temp% in Windows security labs and setup guides without really knowing what they were, so I worked through Microsoft’s documentation (checked on 11 October 2026) and wrote down what actually matters. This post covers what the common variables mean, where they come from and how to view or change them safely.

What is an environment variable?

An environment variable is a named piece of text that Windows hands to every program it starts. Each process gets an environment block, a list of NAME=value pairs. Microsoft’s environment variables documentation explains that there are two types, user variables (set for each user) and system variables (set for everyone), and that a child process inherits the environment of its parent by default.

That inheritance is the key idea. When you open Command Prompt from the Start menu, it inherits the environment from Explorer. Any program you start from that Command Prompt inherits it from there. That’s why changing a variable in one window doesn’t magically change it in programs that are already running.

A few more rules from the same page:

  • A variable name can’t contain an equals sign (=).
  • A user-defined variable can be up to 32,767 characters long.
  • Names aren’t case-sensitive on Windows, so %WINDIR%, %windir% and %WinDir% are the same thing.

What %windir% and %SystemRoot% mean

Microsoft’s list of recognised environment variables describes WINDIR as the variable that “refers to the Windows folder located on the system drive” and lists SYSTEMROOT as “same as WINDIR”. Its typical value is C:\Windows.

So why do both exist? Historically, %SystemRoot% belongs to the Windows NT family, while %windir% was already used by the older DOS-based versions of Windows, and both were kept for compatibility. Today they hold the same path on a normal installation, and you’ll see both in Microsoft’s own documentation and registry values. In my experience, %SystemRoot% turns up more in registry paths and service settings, and %windir% more in scripts and Run-box shortcuts.

Useful folders under %windir%:

  • %windir%\System32: What’s there: Core 64-bit system programs and libraries (cmd.exe, notepad.exe, most .msc consoles).
  • %windir%\SysWOW64: What’s there: 32-bit system files on 64-bit Windows.
  • %windir%\System32\drivers\etc: What’s there: The hosts file, which maps names to IP addresses.
  • %windir%\Temp: What’s there: Temporary files used by the system and services.
  • %windir%\Fonts: What’s there: Installed fonts.
  • %windir%\Logs: What’s there: Various Windows log files.

That hosts file comes up a lot in security courses, because malware has historically edited it to redirect websites. It’s protected: you need admin rights to change anything under %windir%.

Common Windows environment variables (list)

These are the variables you’ll meet most often. Typical values are from Microsoft’s recognised variables list and assume Windows is on C: and the user is called mahir.

  • %windir% / %SystemRoot%: C:\Windows (system variable).
  • %SystemDrive%: C: (a drive, not a folder: no trailing backslash) (system variable).
  • %ProgramFiles%: C:\Program Files (system variable).
  • %ProgramFiles(x86)%: C:\Program Files (x86) on 64-bit Windows (system variable).
  • %ProgramData%: C:\ProgramData (application data for all users) (system variable).
  • %ALLUSERSPROFILE%: C:\ProgramData (system variable).
  • %USERPROFILE%: C:\Users\mahir (user variable).
  • %APPDATA%: C:\Users\mahir\AppData\Roaming (user variable).
  • %LOCALAPPDATA%: C:\Users\mahir\AppData\Local (user variable).
  • %TEMP% / %TMP%: C:\Users\mahir\AppData\Local\Temp (user variable).
  • %USERNAME%: mahir (user variable).
  • %COMPUTERNAME%: The PC’s name (system variable).
  • %PATH%: A semicolon-separated list of folders (user and system values combined).
  • %COMSPEC%: C:\Windows\System32\cmd.exe (system variable).

Roaming vs Local AppData: Microsoft describes %APPDATA% (Roaming) as a common repository for application-specific data, which can roam with a user profile on managed networks, and %LOCALAPPDATA% as the home for local, non-roaming application data. Browser caches and large files usually sit in Local; small settings files often sit in Roaming.

How to use environment variables in Explorer and the Run box

You can type a variable anywhere Windows accepts a path:

  1. Press Win + R to open Run.
  2. Type %temp% and press Enter. Your temporary files folder opens.
  3. Try %appdata%, %userprofile%\Downloads or %windir%\System32\drivers\etc.

Explorer’s address bar works the same way. This is handy when a guide says “delete the app’s folder in AppData”: you don’t have to un-hide anything or know the user name, you just type %appdata%.

Clearing %temp% is a classic safe tidy-up: close your programs, open %temp%, select everything and delete it. Windows will skip any file that’s still in use.

Viewing environment variables in Command Prompt

In Command Prompt (cmd.exe) you read a variable by wrapping its name in percent signs:

C:\> echo %windir%
C:\Windows

C:\> echo %USERPROFILE%
C:\Users\mahir

To see everything, use the built-in set command. Microsoft notes that with no parameters it “displays the current environment variable settings”, and that set with part of a name lists every variable that begins with it:

C:\> set
C:\> set prog
ProgramData=C:\ProgramData
ProgramFiles=C:\Program Files
ProgramFiles(x86)=C:\Program Files (x86)

The output above is the typical shape; exact values depend on your PC.

One quirk worth knowing: if a variable doesn’t exist, Command Prompt doesn’t show an error. echo %NOSUCHVAR% simply prints %NOSUCHVAR% back at you, percent signs and all. So if you see the raw name in a script’s output, that’s your clue the variable is misspelt or was never set in that window. In a batch file, if defined NOSUCHVAR echo yes is the tidy way to test for it before you use it.

Temporary vs permanent variables: set vs setx

This is where most beginners get caught out.

set is temporary. set MYVAR=hello creates or changes a variable for the current Command Prompt window and the programs started from it. Close the window and it’s gone. Microsoft’s user environment variables page says the same thing: variables created with set “apply only to the command window in which they are set, and to its child processes”.

setx is permanent. Microsoft’s setx documentation says it writes variables “to the master environment in the registry”. By default it sets a user variable; add /m to set a system variable (which needs an elevated prompt).

setx MYVAR "hello"
setx MYVAR "hello" /m

Three setx gotchas, all straight from the docs:

  1. It doesn’t affect the current window. “Variables set with setx variables are available in future command windows only, not in the current command window.” Open a new window to see the change.
  2. It truncates at 1,024 characters. If you assign more, the content is cropped, and if you were overwriting an existing variable you can lose data.
  3. It expands references. If %PATH% contains %JAVADIR% and you rewrite PATH with setx, the reference is replaced with its current value, so later changes to JAVADIR won’t flow through.

Point 2 and point 3 are why you should never run setx PATH "%PATH%;C:\something". On many PCs, PATH is already near or over 1,024 characters, and that command merges the user and system PATH into your user variable while cropping it. Use the graphical editor below instead.

Environment variables in PowerShell: $Env:windir

PowerShell doesn’t use percent signs. According to Microsoft’s about_Environment_Variables page, you use the $Env: prefix:

$Env:windir
# C:\Windows

$Env:Foo = 'An example'   # current session only
Get-ChildItem Env:        # list every variable

Setting $Env:Foo only changes the current PowerShell session, just like set in Command Prompt. The same page notes that environment variable names are case-sensitive on macOS and Linux, unlike on Windows, so $Env:Path and $Env:PATH are different there. That difference bites people who write cross-platform scripts.

How to edit environment variables in Windows 11 and 10

For permanent changes, the graphical editor is the safest route:

  1. Press Win, type environment variables and choose Edit the system environment variables (or Edit environment variables for your account for user-only changes).
  2. Click Environment Variables….
  3. The top list holds your user variables; the bottom list holds system variables.
  4. Select a variable and click Edit. For Path, Windows shows one folder per line, so you can add, remove or reorder entries without editing one long string.
  5. Click OK in every window, then restart any program that needs the new value.

Behind the scenes, Microsoft documents that system variables live in the registry under HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment, and that programs which change them should broadcast a WM_SETTINGCHANGE message so the shell picks up the update. User variables live under HKEY_CURRENT_USER\Environment.

How PATH works (and why order matters)

PATH is the most important variable for anyone who codes. When you type python or git without a full path, Windows searches the current folder and then each folder listed in PATH, in order, for a matching program. The first match wins.

That has two consequences:

  • “Not recognised as an internal or external command” usually means the program’s folder isn’t in PATH, or you haven’t opened a new terminal since adding it.
  • Order matters for security. If an attacker can write to a folder that appears early in PATH, they can drop a fake python.exe or git.exe there and it will run instead of the real one. Keep user-writable folders out of the system PATH, and check new entries before adding them.

You can see which copy of a program wins with where:

C:\> where python

Environment variables and security: what to look for

Once you know these variables, a lot of security advice makes more sense. Here’s why they keep appearing in labs and incident write-ups.

User-writable folders are where unwanted programs hide. %TEMP%, %APPDATA% and %LOCALAPPDATA% all sit inside your user profile, so any program you run can write there without an admin prompt. That makes them convenient for legitimate apps and for malware alike. When you’re checking a PC for something suspicious, look for unfamiliar .exe files in these folders, especially ones set to start automatically.

Protected folders need elevation. %windir% and %ProgramFiles% are writable only with administrator rights. A program that installs itself there had to get past a UAC prompt (I explain those in what UAC in Windows is), which is a useful clue when you’re working out how something arrived.

Variables are visible to every process you run. Any program started under your account can read your user and system environment variables. They’re fine for configuration, and better than hard-coding secrets in source files, but they aren’t a vault. On a shared PC, don’t store passwords in system variables, and on a server, give each app only the keys it needs.

Scripts should use variables, not hard-coded paths. A script that writes to C:\Users\mahir\Desktop breaks for every other user and on any PC where Windows isn’t on C:. Using %USERPROFILE%\Desktop or %SystemDrive% keeps it portable, and it’s easier to review, because the intent is obvious.

Reading environment variables in code

Environment variables are also how developers keep configuration and secrets out of source code. The same idea runs from a Windows PC up to a cloud host:

import os
print(os.environ.get("WINDIR"))      # C:\Windows on Windows, None on Linux
print(os.environ.get("APPDATA", "not set"))
<?php
echo getenv('windir') ?: 'not on Windows';

Using .get() with a default in Python, or checking getenv()’s false return in PHP, means your script won’t crash on a machine where the variable doesn’t exist. Hosting platforms use the same mechanism for API keys; I used it when setting a Gemini API key on Vercel, so the key never lands in the code repository.

FAQ

What is %windir% in Windows?

%windir% is an environment variable that stores the path of the Windows folder on the system drive, usually C:\Windows. Windows replaces the variable with that path when you use it in the Run box, Explorer, a script or a shortcut.

What is the difference between %windir% and %SystemRoot%?

On a normal installation there’s no difference in value: Microsoft lists SYSTEMROOT as “same as WINDIR”, and both point to the Windows folder. %SystemRoot% comes from the Windows NT line and is common in registry values, while %windir% is older and common in scripts.

Where is %appdata%?

%appdata% points to the Roaming application data folder, typically C:\Users\<username>\AppData\Roaming. %localappdata% points to C:\Users\<username>\AppData\Local. Type either into the Run box to open it.

Is it safe to delete files in %temp%?

Generally yes. %temp% holds temporary files, and Windows won’t let you delete files that are still in use. Close your programs first, then delete what’s left. Don’t delete the Temp folder itself.

What is the difference between set and setx?

set changes a variable only in the current Command Prompt window and its child processes. setx saves the variable permanently in the registry, but the change only appears in new windows, and values longer than 1,024 characters are cropped.

How do I see all environment variables in Windows?

Run set in Command Prompt or Get-ChildItem Env: in PowerShell. For permanent user and system variables, open Edit the system environment variables and click Environment Variables….

Why does my new PATH entry not work?

Programs read their environment when they start, so close and reopen your terminal or editor after editing PATH. Also check the folder you added actually contains the program, and that there isn’t a typo or a stray quote in the entry.

// note

How to read this note.

This is a learning note from studying the web. It is one small topic, written so I can remember it. It is not a course and not a claim that I have finished the subject.

If a sentence is wrong, say so from the contact page and name this title. Drafts never appear here. Related notes, when they exist, are other published posts, and the same sample rule applies to each of them.

Related posts

What Is UAC in Windows? User Account Control Explained for Beginners
Coding tips

What Is UAC in Windows? User Account Control Explained for Beginners

UAC (User Account Control) is the Windows feature that runs your apps with standard rights and asks before anything gets admin power. Here’s how the two tokens, the dimmed secure desktop, the four slider levels and the registry settings fit together.

October 11, 2026 · 13 min read · 1 view

NTFS vs FAT32 vs exFAT: Which Format Should You Use? (Windows 2026)
Coding tips

NTFS vs FAT32 vs exFAT: Which Format Should You Use? (Windows 2026)

Use NTFS for internal Windows drives, exFAT for USB sticks and SD cards you share with a Mac, and FAT32 only for small or old devices. Here are the real limits (4 GB files, 32 GB format cap), the security differences and the commands.

October 11, 2026 · 12 min read · 0 views

Python enumerate(): How to Start at 1 (and 12 Tested Examples)
Coding tips

Python enumerate(): How to Start at 1 (and 12 Tested Examples)

enumerate(items, start=1) gives you a counter that starts at 1 alongside each item. Tested examples for lists, dicts, zip, reversed order, file line numbers and comprehensions, plus why it beats range(len()) and the list.index() trap.

October 11, 2026 · 11 min read · 0 views

PHP Sort Multidimensional Array by Value (usort, Tested)
Coding tips

PHP Sort Multidimensional Array by Value (usort, Tested)

usort($rows, fn($a, $b) => $a['grade'] <=> $b['grade']) sorts by one column. Descending, several columns, UK dates, case-insensitive names, keeping keys and array_multisort.

October 7, 2026 · 17 min read · 13 views