Git Product home page Git Product logo

Comments (5)

sdwheeler avatar sdwheeler commented on June 8, 2024 1

The intent documentation is to document the behavior of PowerShell, not the .NET API. Also, the behavior gets a little more complicated when you compare Windows to non-Windows platforms.

Windows, normally, doesn't allow you to create an environment variable with a null or empty value. You can't do it using the set command in cmd.exe, nor can you do it in the control panel applet that manages environment variables. Also, the set command can't see the null-valued environment variable. It's odd that setx.exe allows you to do it.

C:\>set TEST
Environment variable TEST not defined

C:\>pwsh -noprofile
PowerShell 7.4.1
PS C:\> [System.Environment]::GetEnvironmentVariables([EnvironmentVariableTarget]::User).ContainsKey('TEST')
True

In bash on Linux or zsh on macOS, you can create and export environment variable with a null or empty value.

In all platforms, the PowerShell environment provider is using the same underlying .NET API to get the list of environment variables. On Windows, that API does not list the null-valued variables. On non-Windows, the API includes the null-valued variables. Windows hides the null-valued variables.

With all that said, I think we can update the docs I will reopen and amend your PR with editorial changes.

from powershell-docs.

sdwheeler avatar sdwheeler commented on June 8, 2024

See my comment in the PR - #10851 (comment)

from powershell-docs.

sdwheeler avatar sdwheeler commented on June 8, 2024

The [System.Environment]::GetEnvironmentVariables() method can see the environment variable A, but the PowerShell environment provider can't.

from powershell-docs.

brucificus avatar brucificus commented on June 8, 2024

@sdwheeler Thanks for taking the time to look at this! I experienced a lot of frustration when I took this documentation as fact in the way it is currently written, and I'm definitely hoping to help set it right.

For what it's worth, [System.Environment]::GetEnvironmentVariables() showing the empty environment variable isn't an outlier - it's actually more compatible with other apps than the PowerShell Environment provider is. πŸ€¦β€β™‚οΈ

The documentation stating broadly that all environment variables cannot be blank - regardless how they are consumed (such as by nested processes, as is common in a shell) or produced (such as by parent processes, as in common in nested shells or in software development scenarios), and without an aside stating PowerShell is unusual for this behavior - is incorrectly misleading about all of the environments PowerShell is supported for.

from powershell-docs.

mklement0 avatar mklement0 commented on June 8, 2024

Just a few clarifications:

  • setx.exe doesn't actually work with empty values:

    • Even though it should report an error, it blindly creates an empty REG_SZ registry value, which the system ignores when creating the environment block for a process - and the process-level environment variables are what matter (in most cases).
    • As a probably accidental side effect of how .NET implements lookup of the persisted environment-variable definitions in the registry, it does surface such broken entries; if you omit the [EnvironmentVariableTarget]::User part or specify [EnvironmentVariableTarget]::Process, you'll see that variable is not found, i.e. that the process doesn't see it.
  • The upshot is that on Windows the persistent definition of empty environment variables is effectively not supported.

  • However, the in-process definition of empty environment variables is de facto supported via the Windows API, but this capability - whose intentionality is unclear - is currently not surfaced via .NET APIs, not even on Unix-like platforms, where empty environment variables aren't uncommon, and easily creatable in-process from POSIX-compatible shells.

    • See dotnet/runtime#50554, also for a discussion of why this is problematic, including especially for PowerShell.

A PowerShell example that demonstrates that creating empty-value env. vars. in-process is possible on Windows:

Add-Type -Namespace Demo -Name WinApiHelper -MemberDefinition @'
  [DllImport("kernel32", CharSet = CharSet.Unicode)]
  public static extern bool SetEnvironmentVariable(string lpName, string lpValue);
'@

if ([Demo.WinApiHelper]::SetEnvironmentVariable('NOVALUE', '')) { 
  'Successfully created $env:NOVALUE with no value (empty string).'
} else {
  throw 'Failed to create $env:NOVALUE with no value (empty string).'
}

# Test the existence of the variable.
Get-Item Env:NOVALUE

from powershell-docs.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.