244

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?

1
  • 16
    FYI for most of the answers in this thread: gci is an alias for Get-ChildItem. Commented Jan 11, 2023 at 18:13

10 Answers 10

353

Shorter version:

gci env:* | sort-object name

This will display both the name and value.

Sign up to request clarification or add additional context in comments.

5 Comments

Could you explain why it behaves like that and how your command fixes it, please?
That's the sign of progress because env was too easy. Damn you M$ people.
I want to add that this behavior was something I encountered in PowerShell 4, but as of 5.1+ I can use the variants shown in the question within a script and expect it to display the variable name and value. Note that gci env: will now sort the variables by Name. though gci env:* does not.
I'm assuming that by shorter you mean relative to the OP's own answer. However, the omission of Out-String is crucial with respect to the question as asked. If you simply want to list all environment variables including their values in PowerShell with nice formatting, gci env: will do (no need for *, no need for Sort-Object, as without the * the output is automatically sorted by name).
What's wrong with gci env:|ft? Suffering from something like getting ellipsis for too long values?
114

Shortest version (with variables sorted by name):

gci env:

1 Comment

This has got to be the single, shortest, most helpful powershell command in existence.
27

I finally fumbled my way into a solution by iterating over each entry in the dictionary:

(gci env:*).GetEnumerator() | Sort-Object Name | Out-String

3 Comments

doesn't run on Linux for me. Are you missing gci to get the child items?
I haven't tried this on powershell core, but gci is in my answer. Note that this question is for [powershell] and not [powershell-core], so solutions may not work for the latter.
You can simplify to gci env: | Out-String (in both PowerShell editions). Please reconsider which answer you've accepted, given that you clearly needed an explicit stringification of the [System.Collections.DictionaryEntry] instances (though it is unclear why), which the currently accepted answer lacks. As it stands, the currently accepted answer doesn't addresses your problem, and is also a poor answer to the general question of how to list environment variables in PowerShell, given that gci env: is enough.
20

This command works also:

dir env:

1 Comment

dir and gci are both aliases for Get-ChildItem
18

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

2 Comments

Is the * actually needed? I think it's not.
It's not needed. People seem to use it out of habit. When using Get-ChildItem Env: without the asterisk, it's automatically sorted by name. It is not sorted when using the wildcard.
16

Short version with a wild card filter:

gci env: | where name -like 'Pro*'

1 Comment

You can also skip the pipeline and simply use a wildcard filter with Get-ChildItem. For example: gci env:Pro*
16

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

Comments

13

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

Comments

5

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

1 Comment

Note that [Environment]::GetEnvironmentVariables() returns a hash table you can convert and sort with ([Environment]::GetEnvironmentVariables("User")).GetEnumerator() | %{'{0} = {1}' -f $_.Key, $_.Value} | Sort where %{...} is an alias for ForEach-Object that formats each key-value pair into a string like "key = value". via
0

If you're using PowerShell Core(6 or above) (pwsh: https://github.com/PowerShell/PowerShell), you can also use ls env:

2 Comments

What is list? I see no such command in PowerShell (Core) v7.2.4. Did you mean ls? If so, that's yet another alias for Get-ChildItem and also already stated in the question.
Yeah, it should be ls, sorry for the miss-leading, thanks for your correction @LanceU.Matthews

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.