如何通过PowerShell提取SharePoint列表项的图片附件并备份?
你的问题理解完全没问题!你精准抓住了核心痛点——SharePoint列表项页面的附件信息并没有直接暴露在HTML结构里,而是藏在页面的JavaScript代码中,所以用普通的Invoke-WebRequest只能拿到页面HTML,自然抓不到附件列表。
从JavaScript代码中提取附件信息是可行的
既然你已经定位到附件信息在JS函数里,我们可以通过正则表达式匹配的方式提取这些数据,步骤如下:
- 先获取页面完整源码
# 替换成你的列表项页面URL,注意使用当前用户凭据 $pageContent = Invoke-WebRequest -Uri "https://你的站点URL/Lists/列表名/DispForm.aspx?ID=1" -UseDefaultCredentials | Select-Object -ExpandProperty Content - 用正则匹配JS中的附件数据
从你提供的截图来看,附件信息应该包含文件名(FileName)和服务器相对路径(ServerRelativeUrl)这类字段,我们可以用正则匹配这些内容:# 匹配FileName和ServerRelativeUrl的键值对 $regexPattern = 'FileName:"([^"]+)",ServerRelativeUrl:"([^"]+)"' $attachmentMatches = [regex]::Matches($pageContent, $regexPattern) - 遍历匹配结果,下载附件
把相对路径拼接成完整下载URL,然后保存文件:
注意:这种方法依赖页面JS代码的结构,如果SharePoint更新了页面的JS逻辑,正则可能会失效,所以不是最稳定的方案,但应急完全可行。$siteRootUrl = "https://你的站点URL" # 替换成你的站点根地址 $savePath = "C:\SharePointAttachmentsBackup" # 替换成你的本地保存路径 if (-not (Test-Path $savePath)) { New-Item -ItemType Directory -Path $savePath | Out-Null } foreach ($match in $attachmentMatches) { $fileName = $match.Groups[1].Value # 处理JS中的转义字符,把\\替换回\ $relativeUrl = $match.Groups[2].Value -replace "\\", "" $downloadUrl = $siteRootUrl + $relativeUrl Invoke-WebRequest -Uri $downloadUrl -OutFile "$savePath\$fileName" -UseDefaultCredentials Write-Host "已下载附件:$fileName" }
更可靠的替代方案(无需依赖SharePoint服务器DLL)
其实有比解析JS更稳定的方法,而且完全不需要服务器端的DLL:
方案1:使用SharePoint REST API
REST API是官方提供的结构化数据接口,直接获取附件列表,完全不需要解析页面:
$siteUrl = "https://你的站点URL" $listName = "你的列表名称" $itemId = 1 # 替换为目标列表项ID,或者遍历所有项ID $savePath = "C:\SharePointAttachmentsBackup" if (-not (Test-Path $savePath)) { New-Item -ItemType Directory -Path $savePath | Out-Null } # 调用REST API获取附件列表 $apiUrl = "$siteUrl/_api/web/lists/getbytitle('$listName')/items($itemId)/AttachmentFiles" $response = Invoke-RestMethod -Uri $apiUrl -Method Get -UseDefaultCredentials -Headers @{Accept = "application/json;odata=verbose"} # 下载每个附件 foreach ($attachment in $response.d.results) { $downloadUrl = "$siteUrl$($attachment.ServerRelativeUrl)" Invoke-WebRequest -Uri $downloadUrl -OutFile "$savePath\$($attachment.FileName)" -UseDefaultCredentials Write-Host "已下载附件:$($attachment.FileName)" }
如果要批量处理所有列表项,可以先调用API获取所有项的ID,再循环处理每个项的附件。
方案2:使用PnP PowerShell
PnP PowerShell是微软官方的PowerShell模块,专门用于SharePoint Online和本地版的管理操作,不需要服务器DLL,直接从PowerShell Gallery安装即可:
- 先安装模块(仅需一次)
Install-Module -Name PnP.PowerShell -Force -AllowClobber - 连接站点并批量下载附件
这个方法封装了所有复杂逻辑,代码简洁且稳定性极高,是优先推荐的方案。$siteUrl = "https://你的站点URL" $listName = "你的列表名称" $savePath = "C:\SharePointAttachmentsBackup" if (-not (Test-Path $savePath)) { New-Item -ItemType Directory -Path $savePath | Out-Null } # 连接SharePoint站点(支持Web登录,适合没有本地AD的场景) Connect-PnPOnline -Url $siteUrl -UseWebLogin # 获取所有列表项 $listItems = Get-PnPListItem -List $listName # 遍历每个项下载附件 foreach ($item in $listItems) { $attachments = Get-PnPAttachment -ListItem $item foreach ($att in $attachments) { Get-PnPFile -Url $att.ServerRelativeUrl -Path $savePath -FileName $att.FileName -AsFile Write-Host "已下载项ID $($item.Id) 的附件:$($att.FileName)" } }
内容的提问来源于stack exchange,提问作者Free Url
相关产品推荐
相关产品推荐

