codewario
codewario

Reputation: 21488

Display all environment variables from a running PowerShell script

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

Answers (10)

mklement0
mklement0

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

GaTechThomas
GaTechThomas

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

Farhan khan
Farhan khan

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

WeihanLi
WeihanLi

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

Christopher Scott
Christopher Scott

Reputation: 3156

This command works also:

dir env:

Upvotes: 19

Mauricio_BR
Mauricio_BR

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

Emil
Emil

Reputation: 2346

Short version with a wild card filter:

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

Upvotes: 16

jaymjarri
jaymjarri

Reputation: 3658

Shorter version:

gci env:* | sort-object name

This will display both the name and value.

Upvotes: 326

codewario
codewario

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

Vlad Rudenko
Vlad Rudenko

Reputation: 2859

Shortest version (with variables sorted by name):

gci env:

Upvotes: 107

Related Questions