PowerShell 查找非空 UNC 路径文件夹有效但速度很慢

PowerShell find non-empty UNC path folders works but is very slow

简而言之,我有大约 30 个名为 Document(s) 的文件夹和一个数字,所以

文档
文档2
...
文件 30

在这些文件夹下面,可能是一个客户端文件夹(可以位于多个文档文件夹中)。当我归档这些数据时,我需要找到非空文件夹以 Robocopy 到另一个位置。

此脚本将在所有文档文件夹中搜索正确的客户端名称,然后检查它下面的文件夹是否为空。但它很慢。真的很慢。有什么建议可以加快速度吗?

我不确定 PS 是否统计了所有文件,或者只是检查计数是否 > 0 并继续。我为检查根文件夹大小 > 0 所做的其他尝试也没有 运行 好;他们似乎也想 count/sum 每 file/folder,而我真的只需要知道什么是 > 0 字节。

谢谢

$filePath =  "\path\to\Document*\*"  
$folderName =  "HelloWorld"

Get-ChildItem -Force $filePath -ErrorAction SilentlyContinue | 
Where-Object { ($_.PSIsContainer -eq $true) `
-and ( $_.Name -like "*$folderName*") `
-and (Get-ChildItem -Path $_.FullName -Recurse | 
                Where-Object {$_.PSIsContainer -eq $True `
                    -and $_.GetFileSystemInfos().Count -gt 0 })  } |
Select-Object FullName | format-Table * -AutoSize 

更新

对于@TheMadTechnician:

return 'root' 具有非空子目录的文件夹路径是否正确?例如

\\path\to\Documents3\HelloWorld
\\path\to\Documents19\HelloWorld
\\path\to\Documents20\HelloWorld

$FolderName = "HelloWorld"
$FilePath = "\path\to\Document*$FolderName"

$EmptyPaths = @()
ForEach($Folder in (Get-ChildItem $FilePath -Directory)){
    If((Get-ChildItem "$($Folder.FullName)\*").Count -gt 0){Continue}
    Get-ChildItem $Folder -Recurse -File|ForEach{break}
    $EmptyPaths += $Folder |
    Select-Object FullName | format-Table * -AutoSize 
} 

我认为如果您允许文件系统提供商过滤结果,您将会看到速度的大幅提升。然后你可以使用一个ForEach循环,检查每个文件夹的根文件(如果根目录中有文件就不需要递归,我们可以continue到下一个文件夹),如果没有根文件递归搜索找到的第一个文件上的文件和 break,它将移动到下一个根文件夹:

$FolderName = "HelloWorld"
$FilePath = "\path\to\Document*$FolderName"
$EmptyPaths = @()
$AllRootPaths = Get-ChildItem $FilePath -Directory
ForEach($Folder in $AllRootPaths){
    If((Get-ChildItem "$($Folder.FullName)\*").Count -gt 0){Continue}
    Get-ChildItem $Folder -Recurse -File|ForEach{break}
    $EmptyPaths += $Folder
}
$AllRootPaths | Where{$_ -notin $EmptyPaths} | Select -Expand FullName

我敢打赌这会大大加快您的结果。 运行 这是在托管文件的服务器上的会话中进行的,因此您不必执行 UNC 路径会更快,因为它都是本地的,但我意识到这通常不是一个选项。

由于 break 的行为,我使用 ForEach 循环而不是内联 ForEach-Object 循环,我认为我们这样做会得到更好的结果。

编辑: 我更新了上面的代码以先收集所有根文件夹,然后创建空文件夹列表。然后你可以输出整个文件夹列表,过滤掉空的,它应该给你一个包含文件的文件夹列表。试试上面的代码,看看它是否有效。当我在本地测试时,它对我有用。