Get a list of directory names

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.