I'm using PowerShell 2.0 and I want to pipe out all the subdirectories of a certain path. The following command outputs all files and directories, but I can't figure out how to filter out the files.
Get-ChildItem c:\mypath -Recurse
I've tried using $_.Attributes
to get the attributes but then I don't know how to construct a literal instance of System.IO.FileAttributes
to compare it to. In cmd.exe
it would be
dir /b /ad /s
This question is related to
powershell
powershell-2.0
Use:
Get-ChildItem \\myserver\myshare\myshare\ -Directory | Select-Object -Property name | convertto-csv -NoTypeInformation | Out-File c:\temp\mydirectorylist.csv
Which does the following
Get-ChildItem \\myserver\myshare\myshare\ -Directory
Select-Object -Property name
convertto-csv -NoTypeInformation
Out-File c:\temp\mydirectorylist.csv
My solution is based on the TechNet article Fun Things You Can Do With the Get-ChildItem Cmdlet.
Get-ChildItem C:\foo | Where-Object {$_.mode -match "d"}
I used it in my script, and it works well.
Use
Get-ChildItem -dir #lists only directories
Get-ChildItem -file #lists only files
If you prefer aliases, use
ls -dir #lists only directories
ls -file #lists only files
or
dir -dir #lists only directories
dir -file #lists only files
To recurse subdirectories as well, add -r
option.
ls -dir -r #lists only directories recursively
ls -file -r #lists only files recursively
Tested on PowerShell 4.0, PowerShell 5.0 (Windows 10), PowerShell Core 6.0 (Windows 10, Mac, and Linux), and PowerShell 7.0 (Windows 10, Mac, and Linux).
Note: On PowerShell Core, symlinks are not followed when you specify the -r
switch. To follow symlinks, specify the -FollowSymlink
switch with -r
.
Note 2: PowerShell is now cross-platform, since version 6.0. The cross-platform version was originally called PowerShell Core, but the the word "Core" has been dropped since PowerShell 7.0+.
Get-ChildItem documentation: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-childitem
Use:
dir -r | where { $_ -is [System.IO.DirectoryInfo] }
From PowerShell v2 and newer (k represents the folder you are beginning your search at):
Get-ChildItem $Path -attributes D -Recurse
If you just want folder names only, and nothing else, use this:
Get-ChildItem $Path -Name -attributes D -Recurse
If you are looking for a specific folder, you could use the following. In this case, I am looking for a folder called myFolder
:
Get-ChildItem $Path -attributes D -Recurse -include "myFolder"
A cleaner approach:
Get-ChildItem "<name_of_directory>" | where {$_.Attributes -match'Directory'}
I wonder if PowerShell 3.0 has a switch that only returns directories; it seems like a logical thing to add.
Use:
dir -Directory -Recurse | Select FullName
This will give you an output of the root structure with the folder name for directories only.
Use this one:
Get-ChildItem -Path \\server\share\folder\ -Recurse -Force | where {$_.Attributes -like '*Directory*'} | Export-Csv -Path C:\Temp\Export.csv -Encoding "Unicode" -Delimiter ";"
The accepted answer mentions
Get-ChildItem -Recurse | ?{ $_.PSIsContainer } | Select-Object FullName
to get a "raw string".
But in fact objects of type Selected.System.IO.DirectoryInfo
will be returned. For raw strings the following can be used:
Get-ChildItem -Recurse | ?{ $_.PSIsContainer } | % { $_.FullName }
The difference matters if the value is concatenated to a string:
Select-Object
suprisingly foo\@{FullName=bar}
ForEach
-operator the expected: foo\bar
A bit more readable and simple approach could be achieved with the script below:
$Directory = "./"
Get-ChildItem $Directory -Recurse | % {
if ($_.Attributes -eq "Directory") {
Write-Host $_.FullName
}
}
Hope this helps!
In PowerShell 3.0, it is simpler:
Get-ChildItem -Directory #List only directories
Get-ChildItem -File #List only files
You'll want to use Get-ChildItem to recursively get all folders and files first. And then pipe that output into a Where-Object clause which only take the files.
# one of several ways to identify a file is using GetType() which
# will return "FileInfo" or "DirectoryInfo"
$files = Get-ChildItem E:\ -Recurse | Where-Object {$_.GetType().Name -eq "FileInfo"} ;
foreach ($file in $files) {
echo $file.FullName ;
}
To answer the original question specifically (using IO.FileAttributes):
Get-ChildItem c:\mypath -Recurse | Where-Object {$_.Attributes -and [IO.FileAttributes]::Directory}
I do prefer Marek's solution though (Where-Object { $_ -is [System.IO.DirectoryInfo] }
).
Less text is required with this approach:
ls -r | ? {$_.mode -match "d"}
Source: Stackoverflow.com