Wie erhalte ich mit Get-ChildItem nur Verzeichnisse?


242

Ich verwende PowerShell 2.0 und möchte alle Unterverzeichnisse eines bestimmten Pfads weiterleiten. Der folgende Befehl gibt alle Dateien und Verzeichnisse aus, aber ich kann nicht herausfinden, wie die Dateien herausgefiltert werden.

Get-ChildItem c:\mypath -Recurse

Ich habe versucht $_.Attributes, die Attribute zu verwenden, aber dann weiß ich nicht, wie ich eine Literalinstanz erstellen soll, mit der ich sie System.IO.FileAttributesvergleichen kann. Darin cmd.exewäre

dir /b /ad /s

Antworten:


292

Für PowerShell-Versionen unter 3.0:

Das von zurückgegebene FileInfoObjekt Get-ChildItemhat eine "base" -Eigenschaft PSIsContainer. Sie möchten nur diese Elemente auswählen.

Get-ChildItem -Recurse | ?{ $_.PSIsContainer }

Wenn Sie die rohen Zeichenfolgennamen der Verzeichnisse möchten, können Sie dies tun

Get-ChildItem -Recurse | ?{ $_.PSIsContainer } | Select-Object FullName

Für PowerShell 3.0 und höher:

dir -Directory

20
Ich wünschte, das wäre auf "IsFolder" ausgerichtet.
Xcud

5
xcud: Nicht jede von einem PSDrive dargestellte Hierarchie ist ordnerbasiert.
Joey

10
Die semantische Lücke zwischen "Container" und "Ordner" ist keine, durch die man einen LKW fahren kann.
Xcud

5
@xcud: Siehe iraSenthils Antwort. -Directory und -File funktionieren auch mit Get-ChildItem. Das PSIsContainer-Attribut muss nicht direkt verwendet werden.
Wouter

(Get-ChildItem |? {$ _. PSIsContainer} | Name auswählen) .Name
Jose Ortega

195

In PowerShell 3.0 ist es einfacher:

Get-ChildItem -Directory #List only directories
Get-ChildItem -File #List only files

33
dir ist ein Alias ​​für Get-ChildItem
Chip McCormick

1
@crashmstr Bist du sicher? Ich habe meine PS4.0 überprüft. Für mich dirwar ein Alias Get-ChildItem, und die -Directoryund -FileOptionen funktionierten wie beschrieben. Ich verwendete Befehle echo $PSVersionTable, help dir, dir -Directoryund dir -Filemit diesem Kommentar zu kommen.
Peter Hull

3
Dies sollte die Antwort sein
Chris S

2
lsund dirsind Aliase der Get-ChildItemAuswahl Ihres Giftes
Kolob Canyon

53

Verwenden

Get-ChildItem -dir #lists only directories
Get-ChildItem -file #lists only files

Wenn Sie Aliase bevorzugen, verwenden Sie

ls -dir #lists only directories
ls -file #lists only files

oder

dir -dir #lists only directories
dir -file #lists only files

Fügen Sie die -rOption hinzu, um auch Unterverzeichnisse zu rekursieren .

ls -dir -r #lists only directories recursively
ls -file -r #lists only files recursively 

Getestet unter PowerShell 4.0, PowerShell 5.0 (Windows 10), PowerShell Core 6.0 (Windows 10, Mac und Linux) und PowerShell 7.0 (Windows 10, Mac und Linux).

Hinweis : In PowerShell Core werden Symlinks nicht befolgt, wenn Sie den -rSwitch angeben . Geben Sie den -FollowSymlinkSchalter mit an, um Symlinks zu folgen -r.

Hinweis 2 : PowerShell ist seit Version 6.0 plattformübergreifend. Die plattformübergreifende Version hieß ursprünglich PowerShell Core, aber das Wort "Core" wurde seit PowerShell 7.0+ entfernt.

Get-ChildItem-Dokumentation: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-childitem


2
Dies funktioniert in Powershell 2.0 nicht, was das spezielle Bedürfnis des OP war. die - [/ Dir / Directory] sind keine gültigen Parameter in Powershell 2.0
Ben Personick

21

Ein sauberer Ansatz:

Get-ChildItem "<name_of_directory>" | where {$_.Attributes -match'Directory'}

Ich frage mich, ob PowerShell 3.0 einen Schalter hat, der nur Verzeichnisse zurückgibt. es scheint eine logische Sache zu sein, hinzuzufügen.


1
FYI Powershell 3.0 fügt die -Directoryund -FileFlags hinzu
WickyNilliams


6

Ab PowerShell v2 und neuer (k steht für den Ordner, in dem Sie mit der Suche beginnen):

Get-ChildItem $Path -attributes D -Recurse

Wenn Sie nur Ordnernamen und nichts anderes möchten, verwenden Sie Folgendes:

Get-ChildItem $Path -Name -attributes D -Recurse

Wenn Sie nach einem bestimmten Ordner suchen, können Sie Folgendes verwenden. In diesem Fall suche ich nach einem Ordner mit dem Namen myFolder:

Get-ChildItem $Path -attributes D -Recurse -include "myFolder"

Und mit PS 3.0 o 4.0?
Kiquenet

5
Der Attributparameter scheint nicht in PS2 zu sein, sondern gibt den Fehler "Es wurde kein Parameter gefunden, der mit dem Parameternamen 'Attribute' übereinstimmt". Es funktioniert gut in PS3.
WileCau

5

Bei diesem Ansatz ist weniger Text erforderlich:

ls -r | ? {$_.mode -match "d"}

Dies ist die, die ich verwenden würde.
David Betz

2
Noch kürzer: ls -r | ? {$ _. mode -match "d"}
jyggorath

Dies findet keine komprimierten Ordner
Charles Lambert

7
Weil ein komprimierter Ordner eine Zip-Datei ist
user1594322

Es ist nicht immer nützlich, alles zu wiederholen. Sie könnten einen extrem tiefen und buschigen Baum haben, in dem Sie nur an Verzeichnissen interessiert sind, die genau zwei Ebenen tiefer liegen. 30 Ebenen tiefer zu suchen ist Zeitverschwendung.
Ross Presser

4

Verwenden:

dir -Directory -Recurse | Select FullName

Dadurch erhalten Sie eine Ausgabe der Stammstruktur mit dem Ordnernamen nur für Verzeichnisse.


3

Verwenden:

Get-ChildItem \\myserver\myshare\myshare\ -Directory | Select-Object -Property name |  convertto-csv -NoTypeInformation  | Out-File c:\temp\mydirectorylist.csv

Welches macht das Folgende

  • Rufen Sie eine Liste der Verzeichnisse am Zielspeicherort ab: Get-ChildItem \\myserver\myshare\myshare\ -Directory
  • Extrahieren Sie nur den Namen der Verzeichnisse: Select-Object -Property name
  • Konvertieren Sie die Ausgabe in das CSV-Format: convertto-csv -NoTypeInformation
  • Speichern Sie das Ergebnis in einer Datei: Out-File c:\temp\mydirectorylist.csv

2
Es wäre großartig, wenn Sie jeden Schritt erklären könnten, damit mehr Menschen sehen können, was los ist.
Jazzurro

Dies funktioniert in Powershell 2.0 nicht, was das spezielle Bedürfnis des OP war. die - [/ Dir / Directory] sind keine gültigen Parameter in Powershell 2.0
Ben Personick

2

Ein etwas lesbarerer und einfacherer Ansatz könnte mit dem folgenden Skript erreicht werden:

$Directory = "./"
Get-ChildItem $Directory -Recurse | % {
    if ($_.Attributes -eq "Directory") {
        Write-Host $_.FullName
    }
}

Hoffe das hilft!


2

Sie sollten Get-ChildItem verwenden, um zuerst rekursiv alle Ordner und Dateien abzurufen . Und dann leiten Sie diese Ausgabe in eine Where-Object- Klausel weiter, die nur die Dateien übernimmt.

# 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 ;
}

1

Die akzeptierte Antwort erwähnt

Get-ChildItem -Recurse | ?{ $_.PSIsContainer } | Select-Object FullName

um einen "rohen String" zu bekommen. Tatsächlich werden jedoch Objekte vom Typ Selected.System.IO.DirectoryInfozurückgegeben. Für rohe Zeichenfolgen kann Folgendes verwendet werden:

Get-ChildItem -Recurse | ?{ $_.PSIsContainer } | % { $_.FullName }

Der Unterschied ist wichtig, wenn der Wert mit einer Zeichenfolge verknüpft ist:

  • mit Select-Objectüberraschendfoo\@{FullName=bar}
  • mit dem ForEach-operator das erwartete:foo\bar

1
Select-Object gibt tatsächlich Objekte vom Typ PSCustomObject zurück. Während Sie% (das ist ForEach-Object) verwenden können, um die rohen Zeichenfolgen zu erhalten, wie Sie es getan haben, können Sie auchSelect-Object -ExpandProperty FullName
JamesQMurphy


0

Verwende das hier:

Get-ChildItem -Path \\server\share\folder\ -Recurse -Force | where {$_.Attributes -like '*Directory*'} | Export-Csv -Path C:\Temp\Export.csv -Encoding "Unicode" -Delimiter ";"

0

So beantworten Sie die ursprüngliche Frage speziell (mithilfe von IO.FileAttributes):

Get-ChildItem c:\mypath -Recurse | Where-Object {$_.Attributes -and [IO.FileAttributes]::Directory}

Ich bevorzuge jedoch Mareks Lösung ( Where-Object { $_ -is [System.IO.DirectoryInfo] }).

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.