Powershell: Get-ChildItem -Include does not match directories (folders) when combined with -Directory

Created on 26 Aug 2020  路  3Comments  路  Source: PowerShell/PowerShell

-Include and -Exclude operate on the leaf path components of the _input_ path (pattern) only, even with Get-ChildItem (except if -Recurse is also specified) - while that is counterintuitive in and of itself, it has always worked this way (see #3304 and #8459).

Unexpectedly, however, -Include seems to match _files_ only with Get-ChildItem (unlike with Get-Item), so combining
-Directory with -Include yields no output (except with * as the pattern):

Steps to reproduce

# Windows, macOS, Linux all have top-level u* folders
# The test would succeed with Get-Item (which requires removing -Directory)
Get-ChildItem /* -Include u* -Directory | Should -Not -BeNull

Expected behavior

The test should pass.

Actual behavior

The test fails due to lack of output:

Expected a value, but got $null or empty.

Environment data

PowerShell Core 7.1.0-preview.6
Issue-Question WG-Engine-Providers

Most helpful comment

I've always found the parameters with Get-ChildItem a pain to teach and totally agree that I'd like to have consistency. But if I understand your issue, -Include fails with -Directory but works with -File. I can see this working in a folder:

PS C:\Windows> dir * -include u* -file


    Directory: C:\Windows

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---           8/26/2020 11:11 AM           5321 unsu.log

PS C:\Windows> dir * -include sys* -Directory


    Directory: C:\Windows\System32

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----           8/13/2020  7:37 AM                Sysprep
d----           5/30/2020  2:00 PM                SystemResetPlatform

    Directory: C:\Windows\SysWOW64

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----           12/7/2019  4:50 AM                sysprep

PS C:\Windows>

But in further testing, this works in the root of C:

PS C:\> dir * -include p* -Directory


    Directory: C:\Pluralsight

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
da---            8/1/2017  1:17 PM                published-author-badge

    Directory: C:\Program Files

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----            4/1/2019  4:51 PM                PackageManagement
d----           7/30/2020 11:32 AM                Pale Moon
d----           7/17/2020  3:42 PM                PowerShell
d----            8/4/2020  2:49 PM                Private Internet Access
da---          10/11/2017 10:37 AM                PuTTY

But not this:

PS C:\> dir * -include u* -Directory

Even though there is a Users directory. I'm trying to figure out if this is a PowerShell or a Windows problem.

All 3 comments

If you aren't recursing what value does -Include give you? This:

get-Childtem c:\u* -directory

would seem to get the job done. Or is the inconsistency that is at question? I also wonder if this is an odd Windows thing when in the root of C. If I change locations to C:\Windows, this works.

 dir * -include sys* -Directory

@jdhitsolutions, the value of -Include is twofold:

  • It supports _PowerShell_'s wildcard language (as (implied) -Path does in your example, but I'm contrasting it with the less powerful, legacy-quirks-addled patterns supported by -Filter).

  • It supports specifying _multiple_ patterns, given that the parameter is [String[]]-typed. without having to repeat the parent path.

On a more philosophical note: That there may be better solutions in a given situation is no reason not to fix broken behavior.

In case you're wondering if such questions arise in the real world: https://stackoverflow.com/q/63590402/45375

I've always found the parameters with Get-ChildItem a pain to teach and totally agree that I'd like to have consistency. But if I understand your issue, -Include fails with -Directory but works with -File. I can see this working in a folder:

PS C:\Windows> dir * -include u* -file


    Directory: C:\Windows

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---           8/26/2020 11:11 AM           5321 unsu.log

PS C:\Windows> dir * -include sys* -Directory


    Directory: C:\Windows\System32

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----           8/13/2020  7:37 AM                Sysprep
d----           5/30/2020  2:00 PM                SystemResetPlatform

    Directory: C:\Windows\SysWOW64

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----           12/7/2019  4:50 AM                sysprep

PS C:\Windows>

But in further testing, this works in the root of C:

PS C:\> dir * -include p* -Directory


    Directory: C:\Pluralsight

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
da---            8/1/2017  1:17 PM                published-author-badge

    Directory: C:\Program Files

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d----            4/1/2019  4:51 PM                PackageManagement
d----           7/30/2020 11:32 AM                Pale Moon
d----           7/17/2020  3:42 PM                PowerShell
d----            8/4/2020  2:49 PM                Private Internet Access
da---          10/11/2017 10:37 AM                PuTTY

But not this:

PS C:\> dir * -include u* -Directory

Even though there is a Users directory. I'm trying to figure out if this is a PowerShell or a Windows problem.

Was this page helpful?
0 / 5 - 0 ratings