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

解决PowerShell统计远程服务器文件时的PathTooLongException问题

解决Win Server2012远程文件统计的路径过长问题

针对你遇到的PathTooLongException问题,结合Win Server2012(PowerShell 3.0)的环境限制,以下是几个更高效的解决方案,比你之前用\\?\UNC跨版本执行的方案耗时更少:

方案1:使用Robocopy统计(推荐)

Robocopy是Windows原生工具,Win Server2012自带,天生支持长路径,且枚举文件的速度远快于Get-ChildItem。它可以通过参数直接按修改时间筛选文件,还能输出统计结果。

修改后的脚本如下:

$servers = "server1", "server2"
# 注意:$folder应为远程服务器上的本地路径(如D:\Path\to\folder),而非UNC路径
$folder = "D:\Path\to\folder"

foreach ($server in $servers) {
    $session = New-PSSession -ComputerName $server

    # 统计近30天修改的文件
    $folder_30 = Invoke-Command -Session $session -ScriptBlock {
        # /L:仅列出文件不复制;/MAXAGE:30:筛选30天内修改的文件;/NJH/NJS:去掉冗余的作业头/尾
        $robocopyResult = robocopy $using:folder NULL /L /MAXAGE:30 /NJH /NJS
        # 提取最后一行的文件数量(格式:Total    Files :         X)
        [int]($robocopyResult | Select-Object -Last 1 | Select-String 'Total\s+Files\s+:\s+(\d+)').Matches.Groups[1].Value
    }

    # 统计30-180天修改的文件
    $folder_30_180 = Invoke-Command -Session $session -ScriptBlock {
        $robocopyResult = robocopy $using:folder NULL /L /MINAGE:30 /MAXAGE:180 /NJH /NJS
        [int]($robocopyResult | Select-Object -Last 1 | Select-String 'Total\s+Files\s+:\s+(\d+)').Matches.Groups[1].Value
    }

    # 统计超过180天未修改的文件
    $folder_180 = Invoke-Command -Session $session -ScriptBlock {
        $robocopyResult = robocopy $using:folder NULL /L /MINAGE:180 /NJH /NJS
        [int]($robocopyResult | Select-Object -Last 1 | Select-String 'Total\s+Files\s+:\s+(\d+)').Matches.Groups[1].Value
    }

    Remove-PSSession $session

    # 输出当前服务器的统计结果
    Write-Host "=== $server 统计结果 ==="
    Write-Host "近30天修改文件数:$folder_30"
    Write-Host "30-180天修改文件数:$folder_30_180"
    Write-Host "超过180天未修改文件数:$folder_180`n"
}

注意:如果你的$folder原本是UNC路径(如\\server1\share\folder),在远程会话中需要转换为远程服务器的本地路径(如C:\Shares\folder),否则Robocopy会从远程服务器访问UNC路径,反而增加耗时。

方案2:手动递归遍历(纯PowerShell实现)

如果无法使用Robocopy,可以通过.NET类手动递归枚举文件,绕过Get-ChildItem的长路径限制。这种方式直接调用底层API,支持\\?\格式的长路径。

修改后的脚本如下:

$servers = "server1", "server2"
$folder = "D:\Path\to\folder"

foreach ($server in $servers) {
    $session = New-PSSession -ComputerName $server

    $stats = Invoke-Command -Session $session -ScriptBlock {
        $localFolder = $using:folder
        $now = Get-Date
        $date30 = $now.AddDays(-30)
        $date180 = $now.AddDays(-180)

        # 定义递归统计函数
        function Get-FileCountByDate {
            param(
                [string]$Path,
                [datetime]$LowerBound,
                [datetime]$UpperBound
            )
            $count = 0
            # 枚举当前目录的文件
            try {
                foreach ($file in [System.IO.Directory]::GetFiles($Path)) {
                    $lastWrite = [System.IO.File]::GetLastWriteTime($file)
                    if ($lastWrite -ge $LowerBound -and $lastWrite -lt $UpperBound) {
                        $count++
                    }
                }
                # 递归处理子目录,转换为长路径格式避免异常
                foreach ($dir in [System.IO.Directory]::GetDirectories($Path)) {
                    $longDir = "\\?\$dir"
                    $count += Get-FileCountByDate -Path $longDir -LowerBound $LowerBound -UpperBound $UpperBound
                }
            } catch {
                # 跳过无权限或无法访问的目录
                Write-Warning "无法访问目录:$Path,错误:$($_.Exception.Message)"
            }
            return $count
        }

        # 统计三类文件数量
        [PSCustomObject]@{
            Last30Days = Get-FileCountByDate -Path $localFolder -LowerBound $date30 -UpperBound $now
            Days30To180 = Get-FileCountByDate -Path $localFolder -LowerBound $date180 -UpperBound $date30
            Over180Days = Get-FileCountByDate -Path $localFolder -LowerBound [datetime]::MinValue -UpperBound $date180
        }
    }

    Remove-PSSession $session

    # 输出结果
    Write-Host "=== $server 统计结果 ==="
    Write-Host "近30天修改文件数:$($stats.Last30Days)"
    Write-Host "30-180天修改文件数:$($stats.Days30To180)"
    Write-Host "超过180天未修改文件数:$($stats.Over180Days)`n"
}

这个方案的优势是无需依赖外部工具,但枚举速度比Robocopy慢,适合需要自定义处理逻辑的场景。

方案3:启用系统级长路径支持(需修改系统设置)

如果允许修改远程服务器的系统配置,可以通过注册表启用长路径支持:

  1. 在远程服务器上打开注册表编辑器,定位到HKLM\SYSTEM\CurrentControlSet\Control\FileSystem
  2. 创建或修改LongPathsEnabled(DWORD类型),设置值为1
  3. 重启服务器

启用后,系统层面的路径长度限制会放宽到32767字符,Get-ChildItem可以直接处理更长的路径(无需\\?\格式)。但此方法需要管理员权限和服务器重启,且PowerShell 3.0本身仍有部分API限制,仅作为备选方案。


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

相关产品推荐
方舟 Agent Plan

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

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