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.