Home Dashboard Directory Help
Search

Add enumeration parameter to Get-ChildItem cmdlet to specify Container/Non-container/Both by Kirk Munro


Status: 

Closed
 as Fixed Help for as Fixed


60
0
Sign in
to vote
Type: Suggestion
ID: 308796
Opened: 11/6/2007 7:06:21 AM
Access Restriction: Public
1
Workaround(s)
view

Description

Right now when calling Get-ChildItem, it is quite common that you want to process only items that are containers or only items that are not containers. The only way you can do this currently is to pipeline the results to Where-Object { $_.PSIsContainer } or Where-Object { !$_.PSIsContainer }. This is post-processing filtering which is slower and it is inconvenient.

Since the need to do this is common, I would like to see an additional parameter added to Get-ChildItem that would allow the caller to specify if they only wanted items that are containers, only items that are not containers, or both, with the default value being both to function like it does today. This seems generic enough that it could be done for all providers.
Details
Sign in to post a comment.
Posted by Microsoft on 2/15/2012 at 10:53 AM
The Get-ChildItem cmdlet ("dir") has new parameters, including File, Directory, Hidden, ReadOnly, and System, that make it easier to search for files with particular attributes. It also has an Attributes parameter that lets you search for complex combinations of attributes.
Posted by Andy White1 on 5/19/2010 at 12:01 PM
This would be a really nice feature to have. Another approach might be to support a "-type" parameter, similar to the Unix find command. The "type" could maybe be a .NET type (e.g. FileInfo, DirectoryInfo, etc.) or just a string like "file"/"f" or "directory"/"d".
Posted by Stephen Mills on 4/8/2009 at 8:41 AM
Please add this in the Get-ChildItem cmdlet. When I am doing more than just a dir from the prompt, I almost always want to have either one of the other, but not both. I know you want it to be a generic cmdlet and it should be possible to do that easily enough. If a provider doesn't support containers and someone supplies the option to only list containers, then throw an exception to tell them that. Since it is a new parameter is shouldn't break existing functionality. Depending on the provider you might even be able to use some of the built in methods to do this. Of course if you are looking for generic it might be easier to do it in the cmdlet instead. Either way it would simplify the life of the Admin and/or programmer using PowerShell.

At the same time you did this I hope you also do the same thing for attributes. I don't deal as much with those, but depending on what you are doing, you should filter as much as you can at the provider as possible. As soon as you pipe something, the performance goes down. If you are looking at 200,000 files and only want files that don't have the archive attribute set, I could easily imagine that filtering it in Get-ChildItem would make a large difference, especially if only a small number had the attribute cleared.
Posted by Karl Prosser on 3/2/2009 at 1:59 PM
i think it would be a shame if this didn't get into V2
Posted by Oisín Grehan on 10/10/2008 at 4:03 PM
This is a switch that should be enabled or provided by the underlying provider itself, if possible. A provider may have optimised ways to filter leaf nodes over passing them to gci to do it [the filtering].
Posted by Keith Hill MVP on 2/5/2008 at 9:05 PM
I do this "get dirs only" or "get files only" so often, I think the solution should be terse. How about a couple of switches like -NoContainer and -NoLeaf. These could be put in the same parameter set and it could be fairly terse:

gci -r -noc
gci -r -nol

You could go with -ContainerOnly and -LeafOnly but then these would need to go into separate parameter sets. It could still be terse:

gci -r -c
gci -r -le

The problem with using -Type is that it isn't going to be nice and terse:

gci -r -t Container
gci -r -t Leaf

Although it is still certainly better than having to use a where predicate with PSIsContainer. Also think about the performance implications. Having dirs/files filtered in the provider should be noticeably faster. Please, please consider fixing this for V2!
Posted by Keith Hill MVP on 11/6/2007 at 9:10 AM
This is *so* common that I really get tired of having to append " | where {$_.PSIsContainer}" or "| where {!$_.PSIsContainer}". There needs to be a shortcut for such a common filtering scenario.
Sign in to post a workaround.
Posted by Sylver Dragon on 10/28/2009 at 11:49 AM
I have been able to use the following to get the effect for files and folders:
To get only files:
Get-ChildItem C:\MyFolder\* -Include *.*

To get only Folders:
Get-ChildItem C:\MyFolder\ -Exclude *.*

They both work on the premise that a folder is not seen as a match on *.*

Also, having the full path to the base folder and the asterisk at the end is necessary for the files only version, otherwise the -Include fails and you get nothing back.

For the folders only version, do NOT put the asterisk at the end of the path; otherwise, you get the subfolders. Also, you can use a . or nothing for the folders only version.

For both cases -recurse can be used.

I do know that this will not work for registry keys and vaules, not sure where else it's going to fail, so use at your own risk!