J'ai un script simple qui parcourt une arborescence de répertoires.
function GetSubFolders([IO.DirectoryInfo]$folder) { Write-Host "Getting folder $folder" Get-ChildItem $folder | ? { $_.PSIsContainer } | % { GetSubFolders $_ } }
Si j'appelle GetSubFolders "c: \ temp"
, il échoue pour chaque sous-répertoire trouvé dans c: \ temp:
Get-ChildItem: Impossible de trouver le chemin 'C: \ WINDOWS \ system32 \ somefolder
Où "somefolder" est un sous-répertoire de c: \ temp. La variable $ _
est clairement un objet System.IO.DirectoryInfo
, mais pourquoi est-elle dépouillée de son chemin absolu et soudainement rendue relative au répertoire courant, c: \ windows \ system32? Notez que lors de l'entrée dans cette méthode, il affiche correctement
Obtention du dossier c: \ temp
Ce qui signifie que cela fonctionne une fois, donc cela ne peut pas être un problème avec Get-ChildItem
acceptant un objet DirectoryInfo
comme paramètre. p >
3 Réponses :
Essayez d'utiliser
Get-ChildItem -Path 'c:\temp' -Recurse | ? { $_.PSIsContainer }
L'indicateur de répertoire sera disponible dans la V3. Si vous n'utilisez pas la V3, vous pouvez également utiliser
Get-ChildItem -Path 'c:\temp' -Recurse -Directory
L'indicateur de répertoire est disponible dans la V3. Merci Ansgar Wiechers pour votre commentaire.
function GetSubFolders([IO.DirectoryInfo]$folder) { Write-Host "Getting folder $folder" Get-ChildItem $folder | ? { $_.PSIsContainer } | % { GetSubFolders $_.FullName } } I think you're looking for the property FullName.
C'est ce que j'avais utilisé pour contourner le problème, mais si $ _ est un objet directoryinfo, pourquoi .FullName est-il même requis?
PowerShell travaillant avec des objets. Chaque objet a plus d'une propriété (généralement). Certains d'entre eux devraient donc en renvoyer une (propriété) comme valeur par défaut dans des scénarios spécifiques comme le vôtre. La valeur par défaut dans votre cas serait le nom mais pas le nom complet.
Sinon, comme votre construction peut fonctionner, utilisez $ folder.fullname au début au lieu de $ _. Fullname à la fin
1 autre façon: (gci $ folder -recurse | où {$ _. Mode -like 'd *'}). Fullname | Trier
La solution avec récursivité / pipes est assez inefficace. Comme d'autres l'ont suggéré, il est préférable d'utiliser le commutateur -recurse avec GCI. Mais il existe aussi une alternative avec loop / queue. Cela fonctionnera pour tout type d'objet arborescent - boucle à travers les enfants du nœud racine, et si un enfant a plus de nœuds - ajoutez-le à la file d'attente.
function Get-SubfolderQueue { param([IO.directoryinfo]$dir) $queue = New-Object System.Collections.Queue $queue.Enqueue($dir) While($queue.Count -gt 0) { $curr = $queue.Dequeue() foreach ($d in $curr.GetDirectories()) { Write-Output $d If($d.GetDirectories().Count -gt 0) { $queue.Enqueue($d) } } } }
vous avez essayé d'utiliser un objet "par nom" ou "par position" qui correspond UNIQUEMENT à la propriété
-Name
deGet-ChildItem.
[ grin i >] jetez un œil à ce[io.directoryinfo] 'C: \ temp' | Sélectionnez-Objet-Propriété *
puis comparez-le à la liste de ce(Get-Help Get-ChildItem -Parameter *). Nom
. notez l'absence de nom de propriété-Path
ou -LiteralPath` dans le 1er objet.Pourquoi ça marche une fois, alors, c'est pourquoi je suis perplexe.
je ne sais pas ... ça semble toujours échouer pour moi.