PowerShell / PowerShell

PowerShell for every system!
https://microsoft.com/PowerShell
MIT License
43.55k stars 7.06k forks source link

Wildcards in the middle of a path don't work in Get-ChildItem with -Recurse and -File #21564

Open bugale opened 2 weeks ago

bugale commented 2 weeks ago

Prerequisites

Steps to reproduce

On a standard installation of Windows (with Powershell 7.4.2), running the following two commands:

Get-ChildItem -Path 'C:\Windows\System32\drivers\etc\*' -Recurse
Get-ChildItem -Path 'C:\Windows\System32\drivers\etc\*' -Recurse -File

results in the same output, for example on my machine:

    Directory: C:\Windows\System32\drivers\etc

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---            6/5/2021  3:08 PM            824 hosts
-a---           4/25/2024  6:51 PM            439 hosts.ics
-a---            5/7/2022  8:22 AM           3683 lmhosts.sam
-a---            6/5/2021  3:08 PM            407 networks
-a---            6/5/2021  3:08 PM           1358 protocol
-a---            6/5/2021  3:08 PM          17635 services

If, on the other hand, a part of the path is replaced with an asterisk, the two commands return different output:

C:\Temp> Get-ChildItem -Path 'C:\Windows\System32\*rivers\etc\*' -Recurse -File
C:\Temp> Get-ChildItem -Path 'C:\Windows\System32\*rivers\etc\*' -Recurse

    Directory: C:\Windows\System32\drivers\etc

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---            6/5/2021  3:08 PM            824 hosts
-a---           4/25/2024  6:51 PM            439 hosts.ics
-a---            5/7/2022  8:22 AM           3683 lmhosts.sam
-a---            6/5/2021  3:08 PM            407 networks
-a---            6/5/2021  3:08 PM           1358 protocol
-a---            6/5/2021  3:08 PM          17635 services

i.e. the command Get-ChildItem -Path 'C:\Windows\System32\*rivers\etc\*' -Recurse -File wrongfully returns nothing. Note that passing only -Recurse without -File correctly returns all of the files in the etc directory.

Expected behavior

PS> Get-ChildItem -Path 'C:\Windows\System32\*rivers\etc\*' -Recurse -File

    Directory: C:\Windows\System32\drivers\etc

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---            6/5/2021  3:08 PM            824 hosts
-a---           4/25/2024  6:51 PM            439 hosts.ics
-a---            5/7/2022  8:22 AM           3683 lmhosts.sam
-a---            6/5/2021  3:08 PM            407 networks
-a---            6/5/2021  3:08 PM           1358 protocol
-a---            6/5/2021  3:08 PM          17635 services

Actual behavior

PS> Get-ChildItem -Path 'C:\Windows\System32\*rivers\etc\*' -Recurse -File

Error details

No response

Environment data

PS> 
Name                           Value
----                           -----
PSVersion                      7.4.2
PSEdition                      Core
GitCommitId                    7.4.2
OS                             Microsoft Windows 10.0.22631
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

Workaround

It's possible to workaround the issue by using | Where-Object { !$_.PSIsContainer } instead of -File