powershellget-childitemwhere-object

Powershell : Get-ChildItem piped to Select-Object returns null Directory property when selecting directory


I am using the Get-ChildItem cmdlet with the -Recurse parameter to enumerate all files and directories in a specific path.

If I run : (Get-ChildItem -Path $Path -Recurse | Where-Object -Property Attributes -Value Directory -EQ).Directory, it returns $null.

If I access this same Directory property on a file object, this returns the relative path to the search path. Why isn't the same behaviour observed with a directory object ?


Solution

  • The behavior differs because it's a different kind of object.

    Files are represented by FileInfo objects (which happen to have a Directory property), whereas directories are represented by DirectoryInfo objects (which do not happen to have such a property, but instead has a Parent property for the same purpose).

    You can use Get-Member to discover these output types and their members:

    Get-ChildItem -Path $Path -Recurse |Get-Member
    

    If you just want the path to the parent directory, use Select-Object with Split-Path:

    Get-ChildItem -Path $Path -Recurse |Select Name,@{Name='ParentPath';Expression={ $_.FullName |Split-Path -Parent }}
    

    It's worth noting that PowerShell's provider subsystem attaches an ETS property named PSIsContainer to indicate whether a provider item is a container type (eg. a directory) or a leaf (eg. a file), so you don't need to inspect the Attributes property:

    Get-ChildItem |Where-Object PSIsContainer -eq $true
    

    The file system provider also exposes two parameters to Get-ChildItem with which you can filter up front:

    Get-ChildItem -Directory # get only directories
    Get-ChildItem -File      # get only files