Powershell: provider path notation cannot access objects who's names start with the path separator

Created on 17 Apr 2019  Â·  12Comments  Â·  Source: PowerShell/PowerShell

Steps to reproduce

function \hello {echo hello}
get-content function:\hello

Expected behavior

echo hello

Actual behavior

get-content : Cannot find path 'Function:\hello' because it does not exist.
At line:1 char:1
+ get-content function:\hello
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : ObjectNotFound: (Function:\hello:String) [Get-Content], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand

This seems to affect all provider path constructs, where the provider doesn't actually have a navigable hierarchy, (function:, and variable:) and that the '\' character is a valid character. I also tested using a / and on Windows I got the same behavior. It only seems to affect if that character is used in the first position of the objects name. (hello\ works as expected)

I couldn't seem to locate a means to escape the leading slash, such as can be done with wildcard operators. (EDIT: while it seems to depend on the exact application, either \\ or \\\ has been found to work as an escape, but its not consistent, and doesn't work with wildcards)

Issue-Question

Most helpful comment

recap:

  • function:: is a provider notation.
  • function: is a drive notation
  • The function:: provider implements the function: drive.
  • PowerShell translates drive paths to provider paths with logic that doesn't work for providers that don't actually support hierarchy. And this translation seems to be implemented with some inconsistency by different commands.
  • the 'function::' provider notation still has some issues resolving wildcards, probably because the wildcard provider is still expecting paths with hierarchy separators.

All 12 comments

This also fails to work:

dir function:?h*

It will find other variations, but not items to which the ? could match either \ or /.

Try get-content function:\\hello and ${function:\\hello}.

Indeed, Get-Childitem and Get-Item apparently cannot find such a function name with wildcards, though Get-Item -Path function:\\hello works - though, curiously, Get-item -LiteralPath function:\\hello doesn't and fails quietly.

Try get-content function:\\hello and ${function:\\hello}.

Neither work.

Doubling of : is needed, but doesn't work for \ or /.

I cannot get the Get-Item -Path function:\\hello to work either. It errors that the path does not exist. just dir function: shows that its there, but any attempt to match it fails.

@mklement0 did you mean get-childitem works … just tried dir function:\\hello and that worked. Pretty sure dir is get-childitem.

Yes, dir is Get-ChildItem - best to call cmdlets by their real name here.

I assumed that Get-Item and Get-ChildItem behave the same in this case, which is generally true with non-container items - though I now see that with Get-ChildItem -LiteralPath function:\\hello _does_ work (on macOS and Linux - see next point).

I just realized that my previous examples work on macOS and Linux only; on Windows you need to throw in an additional \; e.g., Get-Item function:\\\hello - except with Get-ChildItem -LiteralPath.

I think it's fair to conclude we have a mess on our hands.

I can confirm that on Windows, ${function:\\\hello} does work. The first one gets 'root' and the next two form an escape? Get-Item works the same way. Get-ChildItem only needs two \. I can get Get-Content to work only if I pipe the result from Get-Item to it. (gi function:\\\hello | gc)

One would expect the provider: notation to work fairly consistently, in particular where in each situation they are an 'argument' (to almost identical commands). I don't even remember how I stumbled upon this in the first place. I am sure it had to do with testing what were acceptable first characters.

One would expect the provider: notation to work fairly consistently

Hear, hear.

Taking a step back:

  • You could argue that non-hierarchical providers should never need a path separator at all.

  • You could argue that \ should never have been allowed as a legal char. in function names (and other identifiers) - flexibility is nice, but such permissiveness can lead to conceptual confusion and - clearly - technical problems too.

I just stumbled upon something I failed to look at earlier.

the path function::\hello works in all invocations so far. It is consistent.

I realized this because that's what PSPATH results in when other variations worked in get-childitem and get-item.

Is this a lack in documentation, that the : is supposed to be intentionally doubled?

Good find, @msftrncs. I personally have never seen the :: in this context.

Note that Get-Item function::\hell* (wildcards) still doesn't work, however; ditto with Get-ChildItem.

Wildcards work, if the offending character is wildcard'd, ie get-childitem function::?hel*.

recap:

  • function:: is a provider notation.
  • function: is a drive notation
  • The function:: provider implements the function: drive.
  • PowerShell translates drive paths to provider paths with logic that doesn't work for providers that don't actually support hierarchy. And this translation seems to be implemented with some inconsistency by different commands.
  • the 'function::' provider notation still has some issues resolving wildcards, probably because the wildcard provider is still expecting paths with hierarchy separators.

Perhaps we could resolve this by limiting chars which can be used in names. It seems we discussed this previously.

Was this page helpful?
0 / 5 - 0 ratings