You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell中Get-ChildItem搜索网络共享文件过慢求优化

优化网络共享文件夹PDF搜索的PowerShell方案

我花了一周时间(参考Stack Overflow)编写了一段PowerShell代码,用于按名称搜索PDF文件。代码在本地C:\temp文件夹测试时表现良好,但在包含15万+文件的网络共享文件夹(路径\\networkshare)中执行时,Get-ChildItem的搜索速度极慢,现寻求更高效的实现方案。

原代码及运行示例

原代码

$fileName = Read-Host -Prompt 'Enter a File Name'

# Set the path to the folder you want to search
$folderPath = '\\networkshare'

if ($pdfFile = Get-ChildItem -Path $folderPath -Filter "*$fileName*.pdf" -File -Recurse )
{
    & {
        for ($i = 0; $i -lt $pdfFile.Count; $i++)
        {
            [pscustomobject]@{
                $('#' + (' ' * $pdfFile.Count.Length)) = $i + 1
                PDFName = '{0}' -f $pdfFile[$i].BaseName
                Created = '{0}' -f $pdfFile[$i].CreationTime
            }
        }
    } | Out-String -Stream
    $selection = (Read-Host -Prompt 'Enter PDF(s) to open') -split ',' | %'Trim'
    foreach ($selected in $selection)
    {
        $pdf = $pdfFile[$selected - 1]
        Start-Process -FilePath "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" $pdf.FullName
        Write-Host $pdf
        pause 10
    }
}
else
{
    Write-Host -Object "No file with name `"$fileName`" found."
}

代码功能与运行示例

代码功能:提示用户输入要搜索的文件名(仅匹配PDF文件),返回匹配结果后允许用户选择打开指定文件。

示例运行效果:

输入文件名:1234

#  PDFName           Created
-- -------           -------
 1 TK1234            12/14/2022 6:19:45 AM 
 2 TK5467-5001234215 12/24/2022 10:57:36 AM

高效优化方案

优化后代码

$fileName = Read-Host -Prompt 'Enter a File Name'
$folderPath = '\\networkshare'
$searchPattern = "*$fileName*.pdf"

# 使用.NET流式API高效搜索网络共享文件
$pdfFiles = [System.IO.Directory]::EnumerateFiles($folderPath, $searchPattern, [System.IO.SearchOption]::AllDirectories) | ForEach-Object {
    $file = Get-Item $_
    [PSCustomObject]@{
        FullName = $file.FullName
        BaseName = $file.BaseName
        CreationTime = $file.CreationTime
    }
}

if ($pdfFiles) {
    # 格式化输出搜索结果
    $pdfFiles | ForEach-Object -Begin { $index = 1 } -Process {
        [PSCustomObject]@{
            '#' = $index++
            PDFName = $_.BaseName
            Created = $_.CreationTime.ToString()
        }
    } | Format-Table -AutoSize | Out-String -Stream

    # 处理用户选择并打开文件
    $selection = (Read-Host -Prompt 'Enter PDF(s) to open') -split ',' | ForEach-Object { $_.Trim() }
    foreach ($selected in $selection) {
        if ($selected -match '^\d+$' -and $selected -ge 1 -and $selected -le $pdfFiles.Count) {
            $targetFile = $pdfFiles[$selected - 1]
            Start-Process -FilePath "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" -ArgumentList $targetFile.FullName
            Write-Host "Opening: $($targetFile.BaseName)"
            Start-Sleep -Seconds 10
        } else {
            Write-Host "Invalid selection: $selected"
        }
    }
} else {
    Write-Host "No file with name `"$fileName`" found."
}

优化说明

  • 改用.NET流式搜索API:[System.IO.Directory]::EnumerateFiles采用流式返回结果,无需一次性将所有文件对象加载到内存,在大网络目录场景下大幅降低内存占用并提升搜索速度;
  • 精简属性加载:仅获取FullName、BaseName、CreationTime三个必要属性,避免默认加载大量无关文件属性,减少网络传输开销;
  • 优化输出与输入校验:用Format-Table -AutoSize自动调整列宽,同时增加用户输入的有效性校验,避免无效选择导致的错误;
  • 简化逻辑:重构序号生成与结果输出逻辑,代码更易维护。

额外优化建议

  • 如果目标网络共享已启用Windows索引服务,可以使用Get-CimInstance Win32_IndexedFile查询索引数据库,搜索速度会进一步提升;
  • 若知晓PDF文件的存储子目录范围,可缩小搜索路径,避免全目录递归遍历;
  • 对于频繁搜索的场景,可将搜索结果缓存到本地JSON文件,定期更新,减少重复搜索的网络开销。

内容的提问来源于stack exchange,提问作者TMC FAMILY

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 13:20:20