Reputation: 21488
I need to display all configured environment variables in a PowerShell script at runtime. Normally when displaying environment variables I can just use one of the following at the shell (among other techniques, but these are simple):
gci env:*
ls Env:
However, I have a script being called from another program, and when I use one of the above calls in the script, instead of being presented with environment variables and their values, I instead get a list of System.Collections.DictionaryEntry
types instead of the variables and their values. Inside of a PowerShell script, how can I display all environment variables?
Upvotes: 229
Views: 287720
Reputation: 440102
tl;dr
Since you were looking for a friendly string representation of the environment-variable name-value pairs:
# Outputs the friendly, for-display representation of all defined
# environment variables as a (single, multiline) *string*.
# Note: If you just want friendly *to-display* output,
# gci env: *alone* is enough.
gci env: | Out-String
Out-String
returns the friendly for-display representation you'd get by default as a single, multi-line string (albeit one that invariably and unexpectedly has a trailing newline - see GitHub issue #14444), which can be captured and programmatically processed (that said, processing such for-display representations (rather than the original objects) programmatically is rarely the right approach).
If you just want friendly display output, gci env:
alone is enough.
To list the names and values of all environment variables in PowerShell, sorted by name,[1] list the content (child items) of the env:
PowerShell drive using the Get-ChildItem
cmdlet (a built-in alias of which is gci
):
# 'gci' is a built-in alias of the 'Get-ChildItem' cmdlet.
# Avoid alias 'ls', because on Unix-like platforms
# it isn't defined and instead refers to the standard utility of that name.
# The output is implicitly *sorted by variable name*.
gci env:
# Use *wildcards* to list variables by *name pattern*; e.g, all whose
# name starts with "home"
gci env:home*
The above outputs objects, namely instances of [System.Collections.DictionaryEntry]
describing each variable as a name-value pair, with .Key
(.Name
) and .Value
properties. PowerShell's for-display formatting system automatically renders these in a friendly two-column format.
To list environment-variable names only:
gci env: -Name
# Alternative, using property access:
(gci env:).Name
To get a specific environment variable's value, e.g. the value of USERNAME
, it's easiest to use namespace variable notation:
# Output the value of environment variable "USERNAME"
$env:USERNAME
# Alternative, using gc (alias of Get-Content)
# Needed if the name is stored in a variable.
gc env:USERNAME
If you stringify these objects with (potentially implied) .ToString()
:
In Windows PowerShell, they uselessly stringify as their type name, i.e. as verbatim 'System.Collections.DictionaryEntry'
In PowerShell (Core) 7, they now more meaningfully stringify as '[<name>, <value>]'
Try with (%
is a built-in alias of the ForEach-Object
cmdlet):
gci env: | % ToString
# Ditto with Write-Host, which also uses .ToString() stringification
gci env: | Write-Host
If you want to stringify them as they would print to the display, using the friendly two-column format, use the Out-String
cmdlet:
# Outputs *friendly* string representations
gci env: | oss # 'oss' is a built-in wrapper function for 'Out-String -Stream'
Note: If you use Out-String
without -Stream
, you get a single, multi-line string as the output, though note that it will have a trailing newline.[2]
[1] Note that using Get-ChildItem
/ gci
with env:*
, i.e. wildcard character *
following the drive specification env:
- is not only unnecessary for getting all variables, it actually results in unsorted output.
[2] That a trailing newline is invariably appended is problematic, as discussed in GitHub issue #14444
Upvotes: 15
Reputation: 6113
Long environment variable values get truncated by default.
This is one quick way to get a sorted list of environment variables, with full values:
Get-ChildItem env:* | Sort-Object Name | Format-List
Upvotes: 12
Reputation: 51
There are several ways to get all environment variables in Powershell
[System.Environment]::GetEnvironmentVariables()
or
dir env:
To get environment variable by name
[System.Environment]::GetEnvironmentVariable("USERNAME")
$env:USERNAME
Upvotes: 5
Reputation: 107
If you're using PowerShell Core(6 or above) (pwsh: https://github.com/PowerShell/PowerShell), you can also use ls env:
Upvotes: 0
Reputation: 181
I don't think any of the answers provided are related to the question. The OP is getting the list of Object Types (which are the same for each member) and not the actual variable names and values. This is what you are after:
gci env:* | select Name,Value
Short for:
Get-ChildItem Env:* | Select-Object -Property Name,Value
Upvotes: 18
Reputation: 2346
Short version with a wild card filter:
gci env: | where name -like 'Pro*'
Upvotes: 16
Reputation: 3658
Shorter version:
gci env:* | sort-object name
This will display both the name and value.
Upvotes: 326
Reputation: 21488
I finally fumbled my way into a solution by iterating over each entry in the dictionary:
(gci env:*).GetEnumerator() | Sort-Object Name | Out-String
Upvotes: 26