PowerShell icon indicating copy to clipboard operation
PowerShell copied to clipboard

Get-ChildItem does not work with -Path '\\?\'

Open DarkLite1 opened this issue 1 year ago • 3 comments
trafficstars

Prerequisites

Steps to reproduce

We are migrating code from PowerShell 5.1 to PowerShell 7.4.1 while running into the following issue:

$params = @{
    Path    = '\\?\C:\Temp' # does not work in PowerShell 7.4.1, but does in 5.1
    Recurse = $true
    Filter  = '*.ps1'
    Force   = $true
}
Get-ChildItem @params

We are working in a mixed environment where most of the machines are still running PowerShell 5.1 and most of the files are deeply rooted. This is why we use the \\?\ syntax, to allow PowerShell to not stumble upon "Path too long" errors.

Expected behavior

We are expecting all .ps1 files to be found in both versions of PowerShell.

Actual behavior

In PowerShell 7.4.1 no file is found when using Path = '\\?\C:\Temp'.

Error details

No response

Environment data

Name                           Value
----                           -----
PSVersion                      7.4.1
PSEdition                      Core
GitCommitId                    7.4.1
OS                             Microsoft Windows 10.0.20348
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Visuals

No response

DarkLite1 avatar Jan 19 '24 14:01 DarkLite1

Use -LiteralPath instead of -Path

PS. I don't remember UNC path ever working in PowerShell Core, I might be wrong.

237dmitry avatar Jan 19 '24 14:01 237dmitry

? is a wildcard character, if I escape it, it works as I would expect:

PS C:\Users\Martin> Get-ChildItem -Path '\\`?\C:\Temp2'

        Directory: \\?\C:\Temp2


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a---          19-01-2024   16:07            0 B TestFile.txt

PS C:\Users\Martin> Get-ChildItem -Path '\\?\C:\Temp2'
PS C:\Users\Martin>

The Windows PowerShell behavior seems wrong in comparison:

PS C:\Users\Martin> Get-ChildItem -Path '\\`?\C:\Temp2'
Get-ChildItem : Cannot find path '\\`?\C:\Temp2' because it does not exist.
At line:1 char:1
+ Get-ChildItem -Path '\\`?\C:\Temp2'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (\\`?\C:\Temp2:String) [Get-ChildItem], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

PS C:\Users\Martin> Get-ChildItem -Path '\\?\C:\Temp2'


    Directory: \\?\C:


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----         19-01-2024   16:07                Temp2


PS C:\Users\Martin>

I can't escape it in Windows PowerShell, but if I don't escape it then it's treating it like a wildcard anyway (since it's showing me the contents of C:, rather than what's inside my Temp2 dir).
You can certainly make the argument that it shouldn't have changed in PowerShell because people might rely on the old behavior, but personally I'm of the opinion that breaking changes to fix obviously wrong behavior is fine.

Like @237dmitry said, if you use LiteralPath instead, then it works fine in both versions.

MartinGC94 avatar Jan 19 '24 15:01 MartinGC94

Please see:

  • #10805

mklement0 avatar Jan 19 '24 15:01 mklement0

This issue has been marked as duplicate and has not had any activity for 1 day. It has been closed for housekeeping purposes.

📣 Hey @DarkLite1, how did we do? We would love to hear your feedback with the link below! 🗣️

🔗 https://aka.ms/PSRepoFeedback