3

It appears that PowerShell does not recognize the \\?\ notation. Why not?

=== cmd.exe

C:>ver
Microsoft Windows [Version 10.0.17763.1935]
C:>DIR "\\?\C:\Users\*"
 Volume in drive \\?\C: is Windows
 Volume Serial Number is 1C66-809A

 Directory of \\?\C:\Users

2021-08-04  12:27    <DIR>          .
2021-08-04  12:27    <DIR>          ..
2019-11-25  16:22    <DIR>          Administrator
...               0 File(s)              0 bytes
              28 Dir(s)  81,919,647,744 bytes free

=== Windows powershell.exe

PS C:\Users> $PSVersionTable.PSVersion.ToString()
5.1.17763.1852
PS C:\Users> Get-ChildItem -Path "\\?\C:\Users\*"

    Directory: \\?\C:\Users

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       2019-11-25     15:22                Administrator
...
PS C:\Users>

=== PowerShell Core pwsh.exe

PS C:\Users> $PSVersionTable.PSVersion.ToString()
7.1.4
PS C:\Users> Get-ChildItem -Path "\\?\C:\Users\*"
PS C:\Users>
3
  • I don't know why but Get-ChildItem -LiteralPath "\\?\C:\Users\" works so probably something related to the wildcard matching in -Path Commented Aug 16, 2021 at 16:08
  • 1
    "Why" is easily answered with "because it was written that way"; if you want to know if it's intended or a bug (and if it is a bug, if it's going to be fixed), the PowerShell repo seems like a better bet than SO. A little bit of searching gave me #10805, which looks like it covers this. Commented Aug 16, 2021 at 17:09
  • @phuclv, if you look closely, in PS Core Get-ChildItem -LiteralPath "\\?\C:\Users\" doesn't actually work: while it does produce output, it mistakenly reports the root directory's content (verified on PowerShell Core 7.2.0-preview.8). Commented Aug 16, 2021 at 17:38

2 Answers 2

4

Your path syntax is unrelated to UNC paths; it uses a special prefix[1], \\?\, whose purpose is to opt into support for file-system paths whose length exceeds 259 characters.

In Windows PowerShell (the legacy PowerShell edition that ships with Windows, whose latest and final version is v5.1):

  • \\?\ is supported, as shown in your question.

In PowerShell (Core) 6+ (the cross-platform, install-on-demand edition):

  • \\?\ is no longer needed, because long paths are supported by default.

  • That said, it should still be supported - not least in order to support code that runs in both PowerShell editions - and the fact that it isn't, as of PowerShell 7.2 - situationally resulting in no output, with wildcard paths, Get-ChildItem -Path \\?\C:\Users\*, or with the root directory's content(!), with literal paths Get-ChildItem -LiteralPath \\?\C:\Users - is the subject of GitHub issue #10805.


[1] Such prefixes identify Win32 namespaces. The specifics of \\?\ are explained here.

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

Comments

-1

Given this convention is specific to Win32 (and PowerShell has been re-written to be cross-platform), it is likely that this is simply not supported any longer.

If you have other parts of the code that expect this format, a well-placed inline -replace can strip it off

$("\\?\C:\Users\*" -replace '\\\\\?\\', '')

5 Comments

it has nothing to do with the URI format. It's the fully-qualified name
The \\?\ prefix disables file name normalization so you can create files with very long path, or files with invalid characters (because NTFS is fully POSIX-compatible and allows files with any characters except NUL and /) Where is the use of “\\?\” defined?, Why can't I mkdir \\?\%temp%\very\long\path in cmd.exe?, How can use CD command in command prompt to change to a folder named only with a space?
per the link: Many but not all file I/O APIs support "\\?\"; you should look at the reference topic for each API to be sure. given this is Win32 documentation, probably best to avoid it as PowerShell has been rewritten to be cross-platform. @phuclv -- thanks for the links -- used that info to update my answer.
actually the file name is received by FileSystemProvider which calls DirectoryInfo.GetFiles and ends up in the Find­First­File and FindNextFile in the Windows implementation which understands \\?\ so the path format shouldn't affect the output. And this still doesn't answer the question which is why it occurs
The short of it: PowerShell Core no longer needs the \\?\ prefix, because it supports long paths by default. However, the prefix should still be supported - not least in order to facilitate writing cross-edition code - and the fact that it isn't as of v7.2 should be considered a bug - see GitHub issue #. /cc @phuclv

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.