lit
lit

Reputation: 16266

Why doesn't PowerShell Core 7 recognize UNC paths when Windows PowerShell and cmd do?

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>

Upvotes: 3

Views: 1224

Answers (2)

mklement0
mklement0

Reputation: 440162

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.

Upvotes: 4

chris-peterson
chris-peterson

Reputation: 49

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 '\\\\\?\\', '')

Upvotes: -1

Related Questions