Is it possible to filter using Get-ChildItem -Name?

痞子三分冷 提交于 2019-12-12 23:54:01

问题


In one of the questions I answered recently I found interesting answer which shouldn't be working but still was. The question was about how to find specific folder recursively by its name and cd to it.

The answer proposed by A guest who's called Redd was:

Get-ChildItem -Path .\ -Name Folder -Recurse -Depth 10

As per the documentation of Get-ChildItem, -Name parameter is supposed to be SwitchParameter type and is responsible for returning only name (System.String), instead of System.Object.

How it's possible that the solution still works?


MCVE:

# cd C:\SO\56628221
mkdir test, test1, test2, test3
mkdir .\test2\folder
Get-ChildItem -Path .\ -Name Folder -Recurse -Depth 10

Current output:

test2\folder

Expected output:

Get-ChildItem : A positional parameter cannot be found that accepts argument 'Folder'.

What have I tried?

  1. First I checked that -Path is the only positional parameter. Apparently it is:

All the other params have Position: Named.

  1. Then I tried to switch the arguments to something like this:
Get-ChildItem -Path .\ Folder -Name -Recurse -Depth 10

It was still working, so that was clear indication that what I'm passing to the cmdlet is not the value for -Name.

  1. Last thing I supposed was that I just send array of strings to -Path. I tried to do this explicitely:
[string[]]$a = '.\','Folder'
$a.GetType()
Get-ChildItem -Path $a -Name -Recurse -Depth 10

# Output:
PS C:\SO\56628221> $a.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String[]                                 System.Array


PS C:\SO\56628221> Get-ChildItem -Path $a -Name -Recurse -Depth 10
test
test1
test2
test3
test2\folder
Get-ChildItem : Cannot find path 'C:\SO\56628221\Folder' because it does not exist.
At line:1 char:1
+ Get-ChildItem -Path $a -Name -Recurse -Depth 10
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\SO\56628221\Folder:String) [Get-ChildItem], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

回答1:


tl;dr:

Apparently there's an incorrect information in current version of Get-ChildItem documentation, stating that -Filter is no longer positional.

The above is no longer true, it's been fixed in this PR.


Long answer:

In fact, the value 'Folder' is being passed to -Filter parameter. Even though PowerShell 6 documentation says opposite, -Filter is a positional parameter. By mistake, that change was introduced in PowerShell v6+ while PowerShell 5.1 help article for Get-ChildItem is still correct.

The cmdlet you run:

Get-ChildItem -Path .\ -Name Folder -Recurse -Depth 10

is effectively:

Get-ChildItem -Path ".\" -Name -Filter "Folder" -Recurse -Depth 10

Even though -Filter parameter in Get-ChildItem might be tricky in usage, in that case it works perfectly and the filter is applied to only show items named 'Folder'. As that invocation doesn't specify -File or -Directory, if you run:

# Create new file named 'Folder'
New-Item Folder

and then run the cmdlet once again, it'd return both file and folder which was created:

PS C:\SO\56628221> Get-ChildItem -Path .\ -Name Folder -Recurse -Depth 10
Folder
test2\folder

The output is exactly the same if you explicitely use -Filter:

PS C:\SO\56628221> Get-ChildItem -Path .\ -Name -Filter Folder -Recurse -Depth 10
Folder
test2\folder


来源:https://stackoverflow.com/questions/56632954/is-it-possible-to-filter-using-get-childitem-name

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!