Get-ChildItem different commands

Viewed 415

What is the difference between the following commands in PowerShell?

Get-ChildItem C:\Users -Directory

Get-ChildItem C:\Users | Where-Object {$_.PSIsContainer -eq $true}

They both seem to give the same results. Is there a difference at all?

Update:

I have just started learning powershell and I am not familiar with most of terminology. The results on both commands are like the following:


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----          7.9.2021     22.35                Administrator
d-----          7.9.2021     15.40                MyDevice
d-r---          6.5.2020     11.59                Public
d-----          7.9.2021     22.45                student
1 Answers

There's great information in the comments; let me try to distill and complement it:

  • Where-Object { $_.PSIsContainer -eq $true } (or, better, Where-Object { $_.PSIsContainer }) for limiting Get-ChildItem's output to directories as well as Where-Object { -not $_.PSIsContainer } for limiting output to files were only needed up to the (long obsolete) v2 of PowerShell, as Olaf points out.

  • v3 introduced the dynamic -Directory and -File switch parameters to Get-ChildItem to allow direct filtering of the output to directories / files only.

Functionally, the two commands in your question are equivalent, but use of -File / -Directory is not only more concise, but also faster, because needing to involve two commands in the pipeline invariably adds overhead.

  • As Abraham Zinala advises, it is always preferable to filter at the source, which is what -File and -Directory do; so does the -Filter parameter, for limiting output to items whose name matches a wildcard pattern such as *.txt (other cmdlets also support (command-specific) -Filter arguments, and they're always worth using, as they improve performance both in terms of execution speed and memory use).

Note: Strictly speaking, the commands are only equivalent for file-system paths, whereas PowerShell's drive concept also encompasses other types of data stores, via so-called providers.

It is only the FileSystem provider that exposes the -Directory and -File switches (as so-called dynamic parameters).

So for a path related to a different provider - assuming that that provider has an object hierarchy analogous to file-systems involving two item subtypes, leaf items (analogous to files) and container items (analogous to directories) - a separate cmdlet call such as Where-Object { $_.PSIsContainer } may still be needed - unless that provider implements its own analog to the -Directory and -File switches.

Among the providers that ship with PowerShell, the distinction between container and leaf items applies only to the WSMan (drive wsman:) and Certificate providers (drive cert:); the other providers only expose a single item type, either because their data is non-hierarchical (e.g., the Env provider - try Get-ChildItem Env:) or because other entities are exposed as properties rather than as items (the Registry provider, which exposes containers only - registry keys - whereas the registry values are properties of those containers).

Related