Skip to content

Get-ChildItem with FileSystem Provider: behaves inconsequent with -Include #3304

Closed

Description

@schittli

Good evening

If we use the -Include argument with Get-Childitem on the FileSystem Provider, then Get-Childitem changes it's behaviour:

Steps to reproduce

OK: Without the -Include argument Get-ChildItem works as expected:

PS C:\Temp> Get-ChildItem
    Directory: C:\Temp\= EdNe - Beröa
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       10.03.2017     16:48         106678 1001-600x600.jpg
-a----       10.03.2017     16:48          58204 1519-600x600.jpg

Inconsequent and therefore annyoing if we use the -Include Argument

PS C:\Temp> Get-ChildItem -Include @('*.*')
PS C:\Temp> _(no result returned)_

Expected behavior

Of course,
Get-ChildItem -Include @('*.*')
should return the same results as
Get-ChildItem

Actual behavior

If we use the -Include Argument, then Get-ChildItem must process the same directories - independent if we use the -Indlude Argument.

Environment data

Name                           Value
----                           -----
PSVersion                      5.1.14393.693
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.14393.693
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

Activity

  1. SteveL-MSFT commented on Mar 10, 2017

    @SteveL-MSFT
    Member

    Agree that this is not intuitive, but it appears to be by design based on the help:

    -Include <String[]>
            Specifies, as a string array, an item or items that this cmdlet includes in the 
            operation. The value of this parameter qualifies the Path parameter. Enter a path 
            element or pattern, such as *.txt. Wildcards are permitted.
            
            The Include parameter is effective only when the command includes the Recurse 
            parameter or the path leads to the contents of a directory, such as C:\Windows\*, 
            where the wildcard character specifies the contents of the C:\Windows directory.
    
    get-childitem * -Include *.jpg

    Does what you expect.
    I'm not familiar with the history of this provider and why this design was chosen. It seems that if -include is used, it implies * if path is not specified.

  2. schittli commented on Mar 10, 2017

    @schittli
    Author

    Good evening Steve,
    Thank you very much for your answer and help!, yes, I've noted that it is by design.

    But this shouldn't be a reason to not enhance Powershell and wipe out bad design decisions.
    Every programming language is great - if it operates as the programmer expect. If it doesn't, it should be fixed.

    I even think it's much more important for the most used commands, because they annoy every day.
    (In this example, we can not just add -Include *.jpg to an existing command to get what we expect)

    I know it's always a problem if existing commands are changed in their old behaviour, but it can easily be solved by offering good release notes and a global switch, for example using
    #Requires -Version xxx
    or a new one:
    #Uses-Command-Set -Version xxx

    Kind regards, Thomas

  3. SteveL-MSFT commented on Mar 10, 2017

    @SteveL-MSFT
    Member

    Bruce Payette (@BrucePay) do you know the history of this?

  4. Jaykul commented on Mar 11, 2017

    @Jaykul
    Contributor

    What you want is the -Filter parameter.

  5. added
    Issue-Discussionthe issue may not have a clear classification yet. The issue may generate an RFC or may be reclassif
    on Mar 11, 2017
  6. iSazonov commented on Mar 11, 2017

    @iSazonov
    Collaborator

    Interesting result:

    PS C:\temp\a.b>  Get-ChildItem -Include @('*.*')
    
    
        Directory: C:\temp\a.b
    
    
    Mode                LastWriteTime         Length Name
    ----                -------------         ------ ----
    -a----        3/11/2017   7:28 PM              0 Document2.txt

    Here key is "a.b"

  7. mklement0 commented on Mar 11, 2017

    @mklement0
    Contributor

    Joel Bennett (@Jaykul): The -Filter parameter is no real substitute, unfortunately: its provider-specific wildcard language has legacy quirks and fewer features than PowerShell's, and it is limited to one argument. (That said, if its capabilities are sufficient, It is worth using to greatly speed things up.)

    -Include is a generic, provider-independent, array-valued parameter, and what makes its current behavior counter-intuitive is that you'd think that the Child in Get-ChildItem implies that the -Include pattern is applied to *, i.e., all child items, but that's currently not the case. (You do get that behavior if you add -Recurse, but that changes the semantics, obviously).

    By contrast, with Get-Item the current behavior makes sense.

  8. ditta95aR commented on Mar 11, 2017

    @ditta95aR
  9. mklement0 commented on Mar 14, 2017

    @mklement0
    Contributor

    Ilya (@iSazonov): I suspect you know it, but just to spell it out explicitly:

    -Include and -Exclude operate on the leaf component of the -Path value (at least with the Filesystem provider).

    In your case, a.b is the (implied) leaf component, and wildcard *.* matches it, so Get-ChildItem shows the content of C:\temp\a.b.

    (Note that the documentation does a poor job of explaining that.)

    Steve Lee (@SteveL-MSFT):

    It seems that if -include is used, it implies * if path is not specified.

    The fact that * is not implied is the cause of the confusion - in Ilya (@iSazonov)'s example, the wildcard is matched against the directory name FIRST, and only THEN to the names of the items in the directory, as one is likely to expect.
    In other words: The explicit need to specify * - either in isolation for the current dir., or by appending it to an explicit path being passed to -Path - is what constitutes the pitfall.

  10. SteveL-MSFT commented on Mar 14, 2017

    @SteveL-MSFT
    Member

    Michael Klement (@mklement0) that was a typo on my part, I was trying to say * should be implied to make it useful rather than giving no results

  11. mklement0 commented on Mar 28, 2017

    @mklement0
    Contributor

    Because it took me a while to figure it out, I thought I'd share how to get the desired behavior with -Include / -Exclude (in the absence of -Recurse) currently:

    To get what you might expect something like

    Get-ChildItem -Include *.*    # or, mostly, Get-ChildItem -Filter *.*

    to do, you must:

    • switch to Get-Item from Get-ChildItem - if you don't, any child directories among the included items will output their children, not the child directories themselves.

    • use * in the absence of a path / append /* to an existing path; e.g.:

     Get-Item * -Include *.*

    An explanation can be found in this SO answer of mine.

  12. schittli commented on Mar 29, 2017

    @schittli
    Author

    Hi mklement0
    thank you very much for sharing your work!

    btw: It's the best 'chain of evidence' (I don't find the right english term) that the actual implementation is not what we should have.

    kind regards, Thomas

  13. microsoft-github-policy-service commented on Nov 16, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

  14. microsoft-github-policy-service commented on Nov 16, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

  15. microsoft-github-policy-service commented on Nov 16, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

  16. microsoft-github-policy-service commented on Nov 23, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area-FileSystem-Providerspecific to the FileSystem providerIssue-Discussionthe issue may not have a clear classification yet. The issue may generate an RFC or may be reclassifResolution-No ActivityIssue has had no activity for 6 months or moreWG-Cmdletsgeneral cmdlet issuesWG-Engine-Providersbuilt-in PowerShell providers such as FileSystem, Certificates, Registry, etc.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions