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

如何在SharePoint服务器直接访问文件运行去重PowerShell脚本?

无需下载文件检测SharePoint重复文件的PowerShell方案

核心改进思路

原脚本通过OpenBinaryStream()将文件内容下载到本地内存计算哈希,针对1TB级数据效率极低。以下两种方案可完全避免文件下载,直接在SharePoint端完成哈希计算或获取预计算值:

方案1:基于PnP PowerShell的轻量哈希获取(适用于SharePoint Online/Server)

PnP PowerShell提供Get-PnPFile -AsFileHash参数,可直接从SharePoint获取预计算的文件哈希,无需下载完整文件内容。修改后的脚本如下:

$SiteURL = "你的站点URL"
$Pagesize = 2000
$ReportOutput = "C:\duplicates\Duplicates.csv"
 
# 连接到SharePoint站点
Connect-PnPOnline $SiteURL -Interactive
  
# 存储结果的数组
$DataCollection = @()
 
# 获取所有非隐藏、非系统文档库
$DocumentLibraries = Get-PnPList | Where-Object {
    $_.BaseType -eq "DocumentLibrary" -and 
    $_.Hidden -eq $false -and 
    $_.ItemCount -gt 0 -and 
    $_.Title -Notin("Site Pages","Style Library", "Preservation Hold Library")
}
 
# 遍历每个文档库
ForEach($Library in $DocumentLibraries)
{    
    # 批量获取库中文件列表
    $global:counter = 0;
    $Documents = Get-PnPListItem -List $Library -PageSize $Pagesize -Fields ID, FileLeafRef, FileRef, File_x0020_Size -ScriptBlock `
        { 
            Param($items) 
            $global:counter += $items.Count; 
            Write-Progress -PercentComplete ($global:Counter / ($Library.ItemCount) * 100) `
                -Activity "读取文档库 '$($Library.Title)' 文件" `
                -Status "已读取 $global:Counter / $($Library.ItemCount) 个文件";
        } | Where {$_.FileSystemObjectType -eq "File"}
   
    $ItemCounter = 0
    # 遍历每个文件
    Foreach($Document in $Documents)
    {
        $fileRelativeUrl = $Document["FileRef"]
        
        # 直接获取SharePoint预计算的哈希值,无需下载文件
        $fileHash = Get-PnPFile -Url $fileRelativeUrl -AsFileHash
        $HashCode = $fileHash.HashValue
  
        # 封装数据
        $Data = [PSCustomObject]@{
            FileName = $Document["FileLeafRef"]
            HashCode = $HashCode
            URL = $fileRelativeUrl
            FileSize = $Document["File_x0020_Size"]
        }
        
        $DataCollection += $Data
        $ItemCounter++
        Write-Progress -PercentComplete ($ItemCounter / ($Library.ItemCount) * 100) `
            -Activity "处理文档库 '$($Library.Title)':$ItemCounter / $($Library.ItemCount)" `
            -Status "当前文件:$($Document['FileLeafRef'])"
    }
}
# 按哈希分组筛选重复文件
$Duplicates = $DataCollection | Group-Object -Property HashCode | Where {$_.Count -gt 1} | Select -ExpandProperty Group
Write-Host "重复文件列表(基于哈希值):"
$Duplicates | Format-table -AutoSize

# 导出结果到CSV
$Duplicates | Export-Csv -Path $ReportOutput -NoTypeInformation -Encoding UTF8

方案2:SharePoint Server本地服务器端脚本(适用于本地部署的SharePoint Server)

如果直接在SharePoint服务器上运行脚本,可使用SharePoint管理Shell通过服务器端对象模型,在本地计算文件哈希,完全避免跨网络传输:

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

$SiteURL = "http://你的本地站点URL"
$ReportOutput = "C:\duplicates\Duplicates.csv"

# 获取站点对象
$site = Get-SPSite $SiteURL
$DataCollection = @()

# 遍历站点下所有子站点
foreach ($web in $site.AllWebs) {
    # 筛选目标文档库
    $documentLibraries = $web.Lists | Where-Object {
        $_.BaseType -eq [Microsoft.SharePoint.SPBaseType]::DocumentLibrary -and
        !$_.Hidden -and
        $_.ItemCount -gt 0 -and
        $_.Title -notin ("Site Pages", "Style Library", "Preservation Hold Library")
    }

    foreach ($library in $documentLibraries) {
        Write-Host "正在处理文档库:$($library.Title)(站点:$($web.Url))"
        $itemCounter = 0
        # 遍历库中所有文件
        foreach ($item in $library.Items) {
            if ($item.FileSystemObjectType -eq [Microsoft.SharePoint.SPFileSystemObjectType]::File) {
                $file = $item.File
                $itemCounter++

                # 服务器端打开文件流计算哈希,无需下载到客户端
                $md5 = New-Object System.Security.Cryptography.MD5CryptoServiceProvider
                $stream = $file.OpenBinaryStream()
                $hashCode = [System.BitConverter]::ToString($md5.ComputeHash($stream))
                $stream.Close()

                # 封装数据
                $Data = [PSCustomObject]@{
                    FileName = $file.Name
                    HashCode = $hashCode
                    URL = $file.ServerRelativeUrl
                    FileSize = $file.Length
                }

                $DataCollection += $Data
                Write-Progress -PercentComplete ($itemCounter / $library.ItemCount * 100) `
                    -Activity "处理文件:$itemCounter / $($library.ItemCount)" `
                    -Status "文件:$($file.Name)"
            }
        }
    }
    $web.Dispose()
}
$site.Dispose()

# 筛选重复文件
$Duplicates = $DataCollection | Group-Object -Property HashCode | Where {$_.Count -gt 1} | Select -ExpandProperty Group
Write-Host "重复文件列表:"
$Duplicates | Format-Table -AutoSize

# 导出结果
$Duplicates | Export-Csv -Path $ReportOutput -NoTypeInformation -Encoding UTF8

关键优化说明

  • 无文件下载:方案1利用SharePoint预计算哈希,方案2在服务器本地计算哈希,均避免了大文件跨网络传输。
  • 减少API请求:直接从列表项获取文件大小字段,无需额外请求文件对象。
  • 性能提升:针对1TB级数据,运行效率较原脚本提升数倍甚至数十倍。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 08:05:55