我有一个走目录树的简单脚本。
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
对象作为参数并不是什么问题。
答案 0 :(得分:1)
尝试使用
Get-ChildItem -Path 'c:\temp' -Recurse -Directory
目录标志将在V3中可用。如果您不使用V3,也可以使用
Get-ChildItem -Path 'c:\temp' -Recurse | ? { $_.PSIsContainer }
目录标记在V3中可用。 谢谢Ansgar Wiechers的评论。
答案 1 :(得分:1)
function GetSubFolders([IO.DirectoryInfo]$folder) {
Write-Host "Getting folder $folder"
Get-ChildItem $folder | ? { $_.PSIsContainer } | % { GetSubFolders $_.FullName }
}
我认为您正在寻找属性FullName
。
答案 2 :(得分:0)
使用递归/管道的解决方案效率很低。正如其他建议的那样,最好在GCI中使用-recurse开关。但是,还有循环/队列的替代方法。这将适用于任何类型的树对象-遍历根节点的子节点,如果子节点有更多节点,则将其添加到队列中。
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)
}
}
}
}