Author Posts

January 1, 2012 at 12:00 am

by Chris78 at 2012-10-04 01:46:58

Hi,

I'm sure there is a simple solution for this. I have a directory structure that is very deep, and I need a list of all folder names on the first and second levels, but no further.

I know I can use the following script to go through everything (folders only):

gci "C:\MyFolder" -recurse | ?{$_.psiscontainer}

However, this produces a huge, unmanageable list, and also contains information that I don't need, such as LastWriteTime and Length.

Ideally, I would want the script to look at all folders in "C:\MyFolder" and all folders in "C:\MyFolder\MyNextFolder", "C:\MyFolder\MyNextFolder2", "C:\MyFolder\MyNextFolder3" etc. etc., and return only the names of the folders with no other information.

I tried the following to just get names:

gci "C:\MyFolder" -name -recurse | ?{$_.psiscontainer}

But it just sits there for ages – most likely because of the amount of folders in there.

Is this possible?

Thanks,

Chris

by MattG at 2012-10-04 03:30:43

Just call Get-ChildItem on the folders returned but don't call '-recurse'

Get-ChildItem 'C:\MyFolder'| Where-Object {$_.PSIsContainer} | Get-ChildItem | Where-Object {$_.PSIsContainer}

by poshoholic at 2012-10-04 07:21:33

I think what you're actually looking for is this:
Get-ChildItem C:\MyFolder -Recurse | Where-Object {$_.PSIsContainer} | Select-Object -ExpandProperty FullName
Or if you're using PowerShell 3, you can do it this way instead:
Get-ChildItem C:\MyFolder -Recurse -Directory | ForEach-Object FullName
Here's another PowerShell 3 way of doing it:
(Get-ChildItem C:\MyFolder -Recurse -Directory).FullName

by Klaas at 2012-10-05 00:47:51

Or
get-childitem -recurse -directory -name

It's the part of the question to limit the overview to 2 levels that makes it a bit more difficult. I suppose the way to do it is to nest two Get-Childitem cmlets without the -recurse switch like Matt suggested. But then the trick is to get the output format right. When using the pipeline maybe Tee-object might be useful. If not you will probably have to use a Foreach-Object to write both the current folder and the child directories.
I tried to use get-childitem -recurse -directory -name and filter out anything that contains more than 2 backslashes: -Exclude *`\*´\*`\* but it doesn't work. Maybe a more complex matching would do it.

by mjolinor at 2012-10-09 07:35:14

Or this:
(cmd /c dir c:\MyFolder\ /b /s /a:d) -match '^.+?\\.+?\\?.+\\?' | sort

by JeffH at 2012-10-09 07:53:36

This is a v3 command that works.

dir -Directory | foreach { $_ ; dir $_ -Directory} | select -expand fullname

by JeffH at 2012-10-09 07:55:33

The v2 syntax is a little more complicated.

PS C:\work> dir | where {$_.PSIscontainer} | foreach {$_ ; dir $_ | where {$_.psiscontainer}} | select -expand fullname

C:\work\test
C:\work\Test Rig 2
C:\work\test2
C:\work\test3
C:\work\test3\a
C:\work\test4
C:\work\test4\a
C:\work\Ubuntu12

My 'b' and 'c' folders don't get displayed.

by netzambo at 2012-10-09 14:52:57

The following works:

Get-ChildItem "C:\MyFolder" -Recurse -Directory | Where-Object {$_.FullName.split("\").count -le 4} | ForEach-Object FullName

Use how many backslash chars are found in the FullName string based on the result of split.
You said you want maximum of 3 folder ramification "C:\FirstLevel", "C:\FirstLevel\SecondLevel", "c:\Firstlevel\SecondLevel\ThirdLevel"; so you need 3 backslashes and the result of split must be 4 (as in the example above).

by JeffH at 2012-10-10 06:40:22

The downside to this is that you end up parsing text. Think about objects in the pipeline which is what my examples are doing.