我有一个简单的脚本来遍历目录树。
function GetSubFolders([IO.DirectoryInfo]$folder) {
Write-Host "Getting folder $folder"
Get-ChildItem $folder | ? { $_.PSIsContainer } | % { GetSubFolders $_ }
}
如果我调用 GetSubFolders "c:temp"
,则在 c:\temp 中找到的每个子目录都会失败:
Get-ChildItem : 找不到路径 'C:\WINDOWS\system32\somefolder
其中"somefolder"是 c:\temp 的子目录。 变量 $_
显然是一个System.IO.DirectoryInfo
对象,但为什么它被剥夺了绝对路径并突然相对于当前目录 c:\windows\system32? 请注意,进入此方法后,它会正确输出
获取文件夹 c:\temp
这意味着它只能工作一次,因此Get-ChildItem
接受DirectoryInfo
对象作为参数不会成为问题。
function GetSubFolders([IO.DirectoryInfo]$folder) {
Write-Host "Getting folder $folder"
Get-ChildItem $folder | ? { $_.PSIsContainer } | % { GetSubFolders $_.FullName }
}
我认为您正在寻找FullName
物业。
尝试使用
Get-ChildItem -Path 'c:temp' -Recurse -Directory
目录标志将在 V3 中可用。如果您不使用 V3,您还可以使用
Get-ChildItem -Path 'c:temp' -Recurse | ? { $_.PSIsContainer }
编辑:
目录标志在 V3 中可用。谢谢安斯加尔·维彻斯的评论。
递归/管道的解决方案效率非常低。正如其他人建议的那样,最好将-递归开关与GCI一起使用。但是还有一个循环/队列的替代方案。这将适用于任何类型的树对象 - 遍历根节点的子节点,如果子节点有更多节点 - 将其添加到队列中。
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)
}
}
}
}