As a developer, understanding how to manage environment variables in Windows is an important skill. Environment variables act as dynamic configuration settings that control how the operating system, applications, and scripts behave.
In this comprehensive guide, we will dig into how developers can best utilize environment variables by listing, viewing, and modifing them for various automation tasks.
What are Environment Variables?
Environment variables are named values that can affect the way running processes operate in an operating system.
Some key points about environment variables in Windows:
- They influence the environment in which apps, scripts, and commands execute
- Can be used to configure program behaviors without editing files or registry keys
- Help developers control external factors when automating tasks
- Used extensively in CI/CD pipelines and DevOps workflows
- Categorized into user and system variables
Developers often utilize environment variables to build infrastructure-as-code, customize deployment workflows, inject secrets, and assist containerization systems.
Under the hood, they are stored in the Windows registry under keys like:
HKEY_CURRENT_USER\Environment
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
They can also be temporarily set at the command line in cmd or PowerShell sessions.
Now let‘s explore the methods available to list and view environment variables on Windows.
Listing All Environment Variables via Command Line
As developers, we often need to inspect variable values for debugging purposes. The cmd command line provides a simple way to do this.
To output all variables, use the set
command:
C:\> set
This prints out all user and system variables in the form name=value
.
To save the output, you can redirect to a file:
C:\> set > env_vars.txt
Then env_vars.txt
will contain all current variable names and values.
As developers we may want to target either user or system variables separately:
User Variables
set | findstr /i "appdata homepath username temp"
System Variables
set | findstr /i "os procpath systemroot windir"
Using findstr
allows filtering by keyword.
Listing Variables with PowerShell
Windows PowerShell provides some more flexible options for listing environment variables.
To view all user variables:
Get-ChildItem Env:
For all system variables:
Get-ChildItem Env: | Where {$_.Name -like "Path*"}
The Where
filter let‘s us specify criteria.
And to display variables sorted neatly in a table:
dir env:
So as developers, PowerShell allows us to slice and dice variables exactly how we want.
Viewing Variables in Registry Editor
Since environment variables are stored in the registry, we can also view them directly there. The main variable keys are found under:
User Variables
HKEY_CURRENT_USER
\Environment
System Variables
HKEY_LOCAL_MACHINE
\SYSTEM
\CurrentControlSet
\Control
\Session Manager
\Environment
Opening these keys shows all contained variables, their names, types and values.
This helps understand how they are persisted in the registry. It also allows modifying and adding custom variables at the system level by directly editing the registry keys.
Setting and Modifying Variables
Now that we can view environment variables, how do we go about setting and changing them?
Temporarily
Variables can be set temporarily for the current shell session.
On Command Prompt:
set MY_VAR=Hello
PowerShell:
$env:MY_VAR = "Hello"
But these will be discarded once the shell/terminal is closed.
Permanently
For variable changes to persist across reboots and logins, they need to be saved to the Windows registry.
This can be done using the handy setx
command:
setx MY_VAR "Hello"
Verification:
echo %MY_VAR%
Outputs:
Hello
Now MY_VAR
is available globally to any process.
Accessing Variable Values
To actually use environment variable values, there is some important syntax – %var_name%
in Command Prompt or $env:var_name
in PowerShell.
For example, the %USERNAME%
variable contains the current logged in user‘s name.
To output it in PowerShell:
Write-Output "Logged in as $env:USERNAME"
Prints:
Logged in as John
And cmd:
echo Logged in as %USERNAME%
So the proper syntax allows our scripts and programs to leverage environment variables.
Use Cases for Developers
Now that we understand the basics, what are some real-world examples where developers would use environment variables?
Application Configuration
Rather than hardcoding config values like database URLs or API keys, inject them through environment variables. These can then be easily managed separately without touching code.
Secret Management
Sensitive credentials like passwords should never be committed in source code. Environment variables accessed at runtime are a safer solution.
Infrastructure Automation
Tools like Terraform and Ansible rely heavily on environment variables for customizing provisioning flows.
Docker Containerization
Docker defines env vars in images to configure options at container launch time. Settings don‘t need to be baked into images.
CI/CD Pipelines
In build workflows, variables enable tasks to respond to external factors like runtime parameters, execution environments and more.
User Profiles
Applications may rely on variables like TEMP
and APPDATA
to conform to user preferences and permissions.
Comparing Methods for Listing Variables
We covered several approaches to viewing environment variables above:
Method | Pros | Cons |
---|---|---|
Command Prompt | Simple usage | Noisy output |
Universal availability | Hard to parse programatically | |
Powershell | Structured output | Windows only |
Additional filtering and output options | ||
Registry Editor | View storage location directly | Manual process |
Modification capability | ||
So in summary:
- Cmd
set
command – Great quick debugging for developers to dump all variable names and values - PowerShell – Preferred for automation tasks thanks to filtering capacities
- Registry Editor – Allows lower level customization and analysis
Use the method that aligns best with your specific needs as a developer.
Advantages of User vs System Variables
We touched on the difference between user and system environment variables earlier. But what are the implications of that distinction for developers?
User Variables
- Isolated – Unique values per user profile
- Restricted permissions – Protected user-level access
- Persist across sessions – Available globally to given user
- Great for user-specific application preferences and configurations
System Variables
- Global – Common values used by entire system and all users
- Elevated permissions – Requires admin access to modify
- Impact overall environment configurations
- Useful for system-wide defaults, paths, policies
The separation means developers can store user-specific data safely without administrative rights while still being able to customize system-wide configurations as needed.
Potential Security Implications
While environment variables are useful, they do pose some security concerns that developers should keep in mind:
- Sensitive values stored in plain text by default
- Can weaken container isolation boundaries via variable leakage across host and containers
- Variable injection issues possible without proper input sanitization
- Elevation of privilege risks if users can modify restricted system variables
Some best practices include:
- Store secrets like keys and credentials in encrypted formats
- Utilize variable whitelisting instead of blindly injecting unvalidated input
- Separate elevated system variables from user-level variables
- Scrub output logs containing variable values like passwords
Following security hardening measures allows reliably taking advantage of environment variables while limiting risk.
Advanced Usage Examples
Let‘s run through some advanced examples that demonstrate how developers can effectively put environment variables to use.
Cross-platform Scripting
Variables give us a way to write portable cross-platform scripts by abstracting away platform-specific values:
# Set variables
$LogPath = "$env:appdata\logs" # Windows
$LogPath = "$env:HOME/logs" # Linux
# Use variable in path
Get-ChildItem $LogPath
Now the script can adapt to the runtime OS without rewrite.
User Customization
We can customize application start up dynamically based on user environment variables.
If ($env:MYAPP_THEME) {
# Set theme from user variable
Set-Theme $env:MYAPP_THEME
}
Else {
# Default system theme
Set-Theme "Light"
}
This allows user theming without changing application code.
Credentials Vault
Storing unencrypted passwords in code can be easily compromised. With environment variables, we can construct a credentials vault that is more secure.
A script can access credentials only at runtime without exposing them in the raw code. The variables themselves can be encrypted as well for defense in depth.
Cross-Account Resource Access
For a deployment script that needs to provision resources across multiple accounts, inject AWS access keys as variables instead of baking them in:
# Export variables
export AWS_DEV_KEY="xxxxxxx"
export AWS_PROD_KEY="xxxxxxx"
# Use keys
aws --access-key $AWS_DEV_KEY s3 ls # List dev buckets
aws --access-key $AWS_PROD_KEY ec2 describe-instances # List prod instances
This keeps the keys separate from code for improved security.
Conclusion
Environment variables serve many key purposes for developers – customization, configuration, secret management, automation, etc.
By mastering listing, viewing and managing variables in Windows, we can better leverage them in our scripts, applications, workflows and pipelines. The built-in commands and interfaces like cmd, PowerShell and Registry Editor give precision control over tailoring environment variables to suit specific needs.
They do introduce some security considerations around information exposure, access control and input validation. But best practices can help keep risks low.
Overall, environment variables remain an indispensable tool for developers working on the Windows platform. Learning to properly inspect and modify them unlocks more flexible and portable engineering solutions.