Comment obtenir uniquement des répertoires à l'aide de Get-ChildItem?


242

J'utilise PowerShell 2.0 et je veux diriger tous les sous-répertoires d'un certain chemin. La commande suivante génère tous les fichiers et répertoires, mais je n'arrive pas à comprendre comment filtrer les fichiers.

Get-ChildItem c:\mypath -Recurse

J'ai essayé d'utiliser $_.Attributespour obtenir les attributs, mais je ne sais pas comment construire une instance littérale de System.IO.FileAttributespour la comparer. Ce cmd.exeserait

dir /b /ad /s

Réponses:


292

Pour les versions PowerShell inférieures à 3.0:

L' FileInfoobjet retourné par Get-ChildItema une propriété « de base », PSIsContainer. Vous souhaitez sélectionner uniquement ces éléments.

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

Si vous voulez les noms de chaîne bruts des répertoires, vous pouvez le faire

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

Pour PowerShell 3.0 et supérieur:

dir -Directory

20
Souhait alias "IsFolder".
xcud

5
xcud: toutes les hiérarchies représentées par un PSDrive ne sont pas basées sur des dossiers.
Joey

10
L'écart sémantique entre «conteneur» et «dossier» n'est pas celui que vous pouvez traverser.
xcud

5
@xcud: Voir la réponse de iraSenthil. -Directory et -File fonctionnent également sur Get-ChildItem. Pas besoin d'utiliser directement l'attribut PSIsContainer.
Wouter

(Get-ChildItem |? {$ _. PSIsContainer} | Sélectionnez un nom) .Name
Jose Ortega

195

Dans PowerShell 3.0, c'est plus simple:

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

33
dir est un alias de Get-ChildItem
Chip McCormick

1
@crashmstr Êtes-vous sûr? J'ai vérifié sur ma PS4.0. Pour moi, dirétait aliasé Get-ChildItem, et les options -Directoryet -Filefonctionnaient comme décrit. Je commande echo $PSVersionTable, help dir, dir -Directoryet dir -Filede venir avec ce commentaire.
Peter Hull

3
Cela devrait être la réponse
Chris S

2
lset dirsont des alias de Get-ChildItemchoisir votre poison
Kolob Canyon

53

Utilisation

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

Si vous préférez les alias, utilisez

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

ou

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

Pour récupérer également des sous-répertoires, ajoutez une -roption.

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

Testé sur PowerShell 4.0, PowerShell 5.0 (Windows 10), PowerShell Core 6.0 (Windows 10, Mac et Linux) et PowerShell 7.0 (Windows 10, Mac et Linux).

Remarque : Sur PowerShell Core, les liens symboliques ne sont pas suivis lorsque vous spécifiez le -rcommutateur. Pour suivre les liens symboliques, spécifiez le -FollowSymlinkcommutateur avec -r.

Remarque 2 : PowerShell est désormais multiplateforme, depuis la version 6.0. La version multiplateforme s'appelait à l'origine PowerShell Core, mais le mot "Core" a été supprimé depuis PowerShell 7.0+.

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


2
Cela ne fonctionnera pas dans Powershell 2.0 qui était le besoin spécifique de l'OP. les - [/ Dir / Directory] ne sont pas des paramètres valides dans Powershell 2.0
Ben Personick

21

Une approche plus propre:

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

Je me demande si PowerShell 3.0 a un commutateur qui ne renvoie que des répertoires; cela semble être une chose logique à ajouter.


1
FYI powershell 3.0 ajoute les drapeaux -Directoryet-File
WickyNilliams


6

Depuis PowerShell v2 et plus récent (k représente le dossier dans lequel vous commencez votre recherche):

Get-ChildItem $Path -attributes D -Recurse

Si vous ne voulez que les noms de dossier et rien d'autre, utilisez ceci:

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

Si vous recherchez un dossier spécifique, vous pouvez utiliser ce qui suit. Dans ce cas, je recherche un dossier appelé myFolder:

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

Et en utilisant PS 3.0 ou 4.0?
Kiquenet

5
Le paramètre Attributes ne semble pas être dans PS2, il donne une erreur "Impossible de trouver un paramètre correspondant au nom de paramètre 'Attributes'". Cela fonctionne bien sur PS3.
WileCau

5

Moins de texte est requis avec cette approche:

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

C'est celui que j'utiliserais.
David Betz

2
Encore plus court: ls -r | ? {$ _. mode -match "d"}
jyggorath

Cela ne trouve pas les dossiers compressés
Charles Lambert

7
Parce qu'un dossier compressé est un fichier zip
user1594322

Il n'est pas toujours utile de tout reprendre. Vous pourriez avoir un arbre extrêmement profond et touffu où seuls les répertoires vous intéressent exactement deux niveaux plus bas; rechercher trente niveaux plus bas est une perte de temps.
Ross Presser du

4

Utilisation:

dir -Directory -Recurse | Select FullName

Cela vous donnera une sortie de la structure racine avec le nom du dossier pour les répertoires uniquement.


3

Utilisation:

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

Qui fait ce qui suit

  • Obtenez une liste de répertoires dans l'emplacement cible: Get-ChildItem \\myserver\myshare\myshare\ -Directory
  • Extrayez uniquement le nom des répertoires: Select-Object -Property name
  • Convertissez la sortie au format CSV: convertto-csv -NoTypeInformation
  • Enregistrez le résultat dans un fichier: Out-File c:\temp\mydirectorylist.csv

2
Ce serait formidable si vous pouviez expliquer chaque étape afin que plus de personnes puissent voir ce qui se passe.
jazzurro

Cela ne fonctionnera pas dans Powershell 2.0 qui était le besoin spécifique de l'OP. les - [/ Dir / Directory] ne sont pas des paramètres valides dans Powershell 2.0
Ben Personick

2

Une approche un peu plus lisible et simple pourrait être réalisée avec le script ci-dessous:

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

J'espère que cela t'aides!


2

Vous souhaiterez utiliser Get-ChildItem pour obtenir récursivement tous les dossiers et fichiers en premier. Et puis canalisez cette sortie dans une clause Where-Object qui ne prend que les fichiers.

# 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

La réponse acceptée mentionne

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

pour obtenir une "chaîne brute". Mais en fait les objets de type Selected.System.IO.DirectoryInfoseront retournés. Pour les chaînes brutes, les éléments suivants peuvent être utilisés:

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

La différence est importante si la valeur est concaténée à une chaîne:

  • avec Select-Objectétonnammentfoo\@{FullName=bar}
  • avec l' ForEachopératrice:foo\bar

1
Select-Object retournera en fait des objets de type PSCustomObject. Bien que vous puissiez utiliser% (qui est ForEach-Object) pour obtenir les chaînes brutes comme vous l'avez fait, vous pouvez également utiliserSelect-Object -ExpandProperty FullName
JamesQMurphy


0

Utilisez celui-ci:

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

0

Pour répondre spécifiquement à la question d'origine (en utilisant IO.FileAttributes):

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

Je préfère cependant la solution de Marek ( Where-Object { $_ -is [System.IO.DirectoryInfo] }).

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.