KEMBAR78
Namespace variable notation unexpectedly treats paths as wildcard expressions · Issue #9225 · PowerShell/PowerShell · GitHub
Skip to content

Namespace variable notation unexpectedly treats paths as wildcard expressions #9225

@mklement0

Description

@mklement0

Conceptually related: #4726.

Note: Fixing this issue would technically be a breaking change.

PowerShell treats the following:

${<drive>:<name>}

as if you had specified:

Get-Content -Path <drive>:<name>  # or, with assignment, Set-Content -Path ...

This notation - though often used with the Env: drive (e.g., $env:Path) - is little-known as a general paradigm named namespace variable notation, which is explained in this SO answer.

The problem is the use of -Path rather than -LiteralPath (conceptually speaking), because -Path interprets its argument as a wildcard expression.

By design, you can only ever target a single item with namespace notation and if you intentionally specify a wildcard that resolves to multiple items, the statement breaks.

There is no good reason for namespace notation to treat paths as wildcard expressions to begin with, just as it makes no sense to do so for executable invocations and redirections (see #4726).

The fact that they are treated as wildcards causes problems with item names that happen to look like wildcard expressions, in one of two ways:

  • You may not be able to create a new item, such as a new environment variable, at all.
  • Perhaps worse, you may inadvertently target a different, preexisting item.

Taking the example of wanting to assign to / query the value of an environment variable literally named [foo] with ${env:[foo]}, from this SO question:

Steps to reproduce

# Try to create env. var. literally named '[foo]'
${env:[foo]} = 'bar'
# Create a seemingly unrelated env. var. whose name happens to match
# [foo] *if interpreted as a wildcard expression*
$env:o = 'no'
# Get the value
${env:[foo]}

Expected behavior

bar

That is, implicit creation of the variable via namespace notation should succeed, as should subsequent retrieval.

Actual behavior

Cannot find path 'env:[foo]' because it does not exist.
no
  • That is, implicit creation of the variable failed, because the wildcard resolution of [foo] matched nothing and so there was effectively no variable name to assign to / create.

  • ${env:[foo]} unexpectedly retrieved the value of ${env:o}, because [foo] interpreted as a wildcard matches o.

The workaround is to use double `-escaping: ${env:``[foo``]}; that the escape char. must be doubled is an additional quirk - see #7999

Environment data

PowerShell Core 6.2.0-rc.1
Windows PowerShell v5.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue-Questionideally support can be provided via other mechanisms, but sometimes folks do open an issue to get aResolution-No ActivityIssue has had no activity for 6 months or moreWG-Engine-Providersbuilt-in PowerShell providers such as FileSystem, Certificates, Registry, etc.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions