Skip to content

Strange behavior with Get-ChildItem #5269

Description

Steps to reproduce

$Path='C:\temp'
#remove-item "$Path\TestPS"  -recurse
md "$Path\TestPS"
get-childitem -path "$Path\TestPS\F*.txt" -File -Recurse #OK no file

md "$Path\TestPS\D1"
get-childitem -path "$Path\TestPS" -Directory -Recurse #Ok one directory
get-childitem -path "$Path\TestPS\*" -Directory -Recurse #NOK no result

"Test" > "$Path\TestPS\D1\File1.txt"
get-childitem -path "$Path\TestPS\F*.txt" -File -Recurse #OK one file
get-childitem -path "$Path\TestPS" -File -Recurse #OK one file

get-childitem -path "$Path\TestPS\*" -File -Recurse #NOK no result

#Add a file into the 'root' of the search 
"Test" > "$Path\TestPS\File2.txt"
get-childitem -path "$Path\TestPS\*" -File -Recurse #OK two files !!! Different !!!
get-childitem -path "$Path\TestPS\*" -Directory -Recurse #OK one directory !!! Different !!! 


remove-item "$Path\TestPS\File2.txt"
#The 'root' of the search is empty 
get-childitem -path "$Path\TestPS\*" -File -Recurse #NOK no result
get-childitem -path "$Path\TestPS\*" -Directory -Recurse #NOK no result

#original path
#Get-ChildItem -Path 'C:\Users\laurent\AppData\Local\Mozilla\Firefox\Profiles\*.default*' -File -Rec

#it works
#Get-ChildItem -Path 'C:\Users\laurent\AppData\Local\Mozilla\Firefox\Profiles\*.default*' -Rec|Where-Object {-not $_.PSIsContainer}

Expected behavior

The following calls must return existing files or directories :

get-childitem -path 'C:\Temp\TestPS\*" -File -Recurse
get-childitem -path 'C:\Temp\TestPS\*" -Directoyr -Recurse

Actual behavior

When the 'root' of the search ('C:\Temp\TestPS') is empty, the search do not return all entries :

Environment data

> $PSVersionTable
Name                           Value
----                           -----
PSVersion                      6.0.0-beta.9
PSEdition                      Core
GitCommitId                    v6.0.0-beta.9
OS                             Microsoft Windows 6.1.7601 S
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0, 5.0, 5.1.10032.0, 6.0.0}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Same problem with For Windows PowerShell v 5.1.14409.1012 :

> $PSVersionTable 
Name                           Value
----                           -----
PSVersion                      5.1.14409.1012
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0, 5.0, 5.1.14409.1012}
BuildVersion                   10.0.14409.1012
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

Activity

  1. added
    WG-Engine-Providersbuilt-in PowerShell providers such as FileSystem, Certificates, Registry, etc.
    Issue-Questionideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a
    on Oct 29, 2017
  2. SteveL-MSFT commented on Oct 31, 2017

    @SteveL-MSFT
    Member

    It seems that the behavior is that if you have a wildcard, then the recursion is applied to the results of that wildcard expansion. Assume a folder structure like:

    testPS
      d1
        d2
    

    gci testPS\* returns d1 as expected
    now, if you use gci testPS\* -recurse, the -recurse is applied to d1, not testPS due to the wildcard and d2 is returned.

    I agree that the behavior may not seem intuitive, but it does seem (somewhat) logical. I'd be concerned that a change here would not be a breaking change worth making. Perhaps we should just update the documentation?

  3. LaurentDardenne commented on Nov 2, 2017

    @LaurentDardenne
    Author

    Perhaps we should just update the documentation?

    Yes.

    1. According to the help file 'about_Wildcards' :
    
      Wildcard Description        Example  Match             No match
      -------- ------------------ -------- ----------------- --------
      *        Matches zero or    a*       A, ag, Apple      banana
               more characters
    

    Are these statements equivalent (with my first exemple) ?

    $Path='C:\temp'
    get-childitem -path "$Path\TestPS\*" -Recurse 
    get-childitem -path "$Path\TestPS" -Recurse 
    1. According to the help file 'FileSytem' (DYNAMIC PARAMETERS) :
       -File <System.Management.Automation.SwitchParameter>
           Gets files.
    
           The File parameter was introduced in Windows PowerShell 3.0.
    
           To get only files, use the File parameter and omit the Directory parameter. To exclude files, use the
           Directory parameter and omit the File parameter, or use the Attributes parameter.
    
    

    Are these statements equivalent (with my first exemple) ?

    $Path='C:\temp'
    get-childitem -path "$Path\TestPS\*" -File  -Recurse 
    get-childitem -path "$Path\TestPS\*"  -Recurse |Where {-not $_.PSisContainer} 

    If for this last example these statements are equivalent, in my case the resultat is different.

  4. added this to the milestone on Nov 3, 2017
  5. SteveL-MSFT commented on Nov 3, 2017

    @SteveL-MSFT
    Member

    I missed the details about File and agree that it's broken.

  6. LaurentDardenne commented on Feb 8, 2018

    @LaurentDardenne
    Author

    Steve Lee (@SteveL-MSFT) this fix do not should be backported to Windows PowerShell 5.1 ?

  7. SteveL-MSFT commented on Feb 8, 2018

    @SteveL-MSFT
    Member

    Laurent Dardenne (@LaurentDardenne) the concern would be that this is a breaking change so at this time not considered to be ported to 5.1

  8. LaurentDardenne commented on Feb 9, 2018

    @LaurentDardenne
    Author

    OK, thanks.
    How to find the list of these bugs / difference ?
    Can the addition of a label be considered here or should we duplicate this issue on Uservoice?

  9. SteveL-MSFT commented on Feb 9, 2018

    @SteveL-MSFT
    Member

    Laurent Dardenne (@LaurentDardenne) the label indicates we're considering backporting it to Windows PowerShell 5.1. At the time of actual port, we'll determine if it's too risky to port due to risk of regression (since the PSCore6 code base has now deviated quite a bit from the Windows PowerShell code base). Perhaps I'll create a new label Ported-WindowsPowerShell51 to indicate PRs that have been ported.

  10. LaurentDardenne commented on Feb 10, 2018

    @LaurentDardenne
    Author

    Steve Lee (@SteveL-MSFT)
    There is the label '_Breaking-Chang_e' which is very useful when porting code v5.n to v6.n
    A 'Ported-WindowsPowerShell51' label can be useful information.

    This fix does not have the 'Breaking-Change' label, but in the case of a 6.n code port, (based on this corrected behavior) to-> 5.n, how do I find these cases?
    A 'NotPorted-WindowsPowerShell51' label ? :-)
    Or a note inside the Changelog.md file ?

    It is information intended for the users and not for the monitoring of the project.

  11. SteveL-MSFT commented on Feb 12, 2018

    @SteveL-MSFT
    Member

    Laurent Dardenne (@LaurentDardenne) this issue should have had the Breaking-Change label, was just missed. We usually have the Breaking changes at the top of the ChangeLog. We have a work item to have better documentation on porting scripts/modules from 5.1 to 6.

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

    Breaking-Changebreaking change that may affect usersIssue-Questionideally support can be provided via other mechanisms, but sometimes folks do open an issue to get aResolution-FixedThe issue is fixed.WG-Engine-Providersbuilt-in PowerShell providers such as FileSystem, Certificates, Registry, etc.

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions