[玩转系统] 使用 PowerShell 合并 SharePoint 中的重复文件夹
作者:精品下载站 日期:2024-12-14 03:40:01 浏览:15 分类:玩电脑
使用 PowerShell 合并 SharePoint 中的重复文件夹
如果我知道在 SharePoint Online 中合并重复文件夹的方法,该博客的一位读者联系了我。用户已经在重复的文件夹中工作过,因此我们不仅需要合并文件夹,还需要保留最后修改的文件。
所有重复的文件或文件夹的文件名都具有相同的模式 (1)
。因此,这使得查找文件和文件夹并将它们与原始位置合并变得非常容易。
如果您想知道发生了什么;用户在未先停止同步的情况下在本地删除了文件。由于删除的文件数量很大(超过 750,000 个),他们要求 Microsoft 恢复,他们也这样做了。
仅由于通信错误,恢复作业分两部分完成,导致文件重复。 Microsoft 无法协助清理,所以我介入了。
在这种情况下,第三方备份解决方案确实可以成为救星。我之前写过相关文章;您是否需要 Microsoft 365 的备份解决方案。正如您在本例中所看到的,文件可以恢复,但拥有备份解决方案将使恢复变得更加容易。
查找重复项
合并重复的文件夹和文件将需要几个步骤。重复文件夹不仅位于文档库的根级别,还可以位于子文件夹的 3 层深处。因此,我们需要递归地遍历所有文件夹,查找名称中带有 (1) 的项目。
我已将脚本分解为几个步骤,每个步骤都转换为自己的函数:
- 查找重复的文件和文件夹
- 创建目标路径(原始位置)
- 移动文件夹内容
- 比较文件日期
- 移动单个项目
连接到 SharePoint 网站
在我们执行任何操作之前,我们需要连接到 SharePoint 站点。我们可以使用 PnPOnline 简单地完成此操作,并且我在这里使用 Web 登录开关,因此我们可以在这里使用 MFA 进行正常登录。
在文章的最后,我将展示完整的脚本。
# SharePoint url
$sharepointUrl = 'https://a-d.sharepoint.com/'
# Site
$site = 'sites/lab01'
# Library name
$libraryName = 'Duplicates'
# Login
$url = $sharepointUrl+ '/' + $site
Connect-PnPOnline -Url $url -UseWebLogin
查找重复文件
因为我们还需要处理子文件夹,所以这里的技巧是递归地遍历文件夹。我们在这里使用 Get-PnPFolderItem 函数,但随后以递归方式使用。该函数基于 Josh Einstein 的脚本,您可以在此处找到该脚本。
# Recursively calls Get-PnpFolderItem for a given Document Library
# Based on: https://gist.github.com/josheinstein/3ace0c9f8e25d07583ceb57d13f71b2e
Function Get-PnpFolderItemRecursively($FolderSiteRelativeUrl) {
# Get all items
$items = @(Get-PnPFolderItem -FolderSiteRelativeUrl $FolderSiteRelativeUrl)
Foreach ($item in $items) {
# Strip the Site URL of the item path because Get-PnpFolderItem wants it
# to be relative to the site, not an absolute path.
$itemPath = $item.ServerRelativeUrl -replace "^$(([Uri]$item.Context.Url).AbsolutePath)/",''
# Check if the item is a folder
If ($item -is [Microsoft.SharePoint.Client.Folder])
{
# Check if the folder name contains (1) on the end
# If - if the folder name contains a (1) on the end, then it's a duplicate folder that we need to move or merge
# Else - if the folder doesn't contain (1), then we open the folder and search through the next level
if ($item.name -like "*(1)")
{
# Duplicate folder found
Write-Host " - Duplicatie folder found: " $itemPath -ForegroundColor Yellow
# Move the content of the folder to the original location
Move-FolderItemsRecursively($itemPath)
}
else
{
# Is doesn't contain (1), but it's a folder, search through the next level by recursing into this function.
Get-PnpFolderItemRecursively $itemPath
}
}
else
{
# Item is a file
# Check if items name contains a (1), if true, move the file
if ($item.name -like "*(1)")
{
$targetPath = Create-TargetPath -itemPath $itemPath -targetPath $item["FileRef"].trim("*(1)") -relativePath $relativePath
Write-Host $newTargetPath;
Move-CustomItem -SiteRelativeUrl $itemPath -targetPath $targetPath -item $item
}
# Else skip to next
}
}
}
因此,对于每个项目,我们都会检查它是否是一个文件夹。当它是一个文件夹时,我们检查文件夹名称是否包含(1)。如果是,我们将移动文件夹内容,如果不是,我们“打开”文件夹并浏览内容。
如果它不是文件夹,而是文件,那么我们再次检查名称。如果它包含 (1),那么我们将移动该文件,否则我们什么都不做。
创建目标路径
如果我们发现重复的项目,我们需要从该项目的路径创建原始路径。我们还需要检查原始文件夹是否存在,如果不存在则重新创建原始文件夹。
Function Create-TargetPath {
[CmdletBinding()]
param(
[parameter (Mandatory=$true)]
$itemPath,
[parameter (Mandatory=$true)]
$item,
[parameter (Mandatory=$false)]
$relativePath
)
process
{
# Build new path
$path = $itemPath.replace($item.name,'')
$targetPath = "/" + $site + "/" + $path + $item.name
if ($whatIf -ne $true)
{
# Check if target folder exists, create if necessary
Write-host ' - Check if target folder exists' $path.replace('(1)', '') -BackgroundColor DarkMagenta;
$result = Resolve-PnPFolder -SiteRelativePath $path.replace('(1)', '') -ErrorAction SilentlyContinue
}
else{
Write-host ' - Create target folder if it does not exists' $path.replace('(1)', '') -BackgroundColor DarkMagenta;
}
Write-Output $targetPath.replace('(1)', '')
}
}
您将在每个函数中看到我正在使用变量 $whatIf。在脚本的开头,我声明了这个变量。这使我可以测试脚本,而无需实际移动或创建任何文件或文件夹。
大多数 PnP 函数确实支持 WhatIf 开关,但例如 Resolve-PnPFolder 不支持它。这样我就可以通过向控制台写入脚本将执行的操作来简单地测试它。
create-targetPath 函数将重新创建路径,检查文件夹是否存在,如果不存在,则使用 Resolve-PnPfolder 函数重新创建它。
使用 PowerShell 移动文件夹和子文件夹
当我们找到重复的文件夹时,我们希望将该文件夹和所有内容(包括子文件夹)移动到原始位置。对于每个子文件夹,我们还需要创建一个目标路径。
Function Move-FolderItemsRecursively($FolderSiteRelativeUrl) {
# Get all items in this sub folder
$items = @(Get-PnPFolderItem -FolderSiteRelativeUrl $FolderSiteRelativeUrl)
foreach ($item in $items) {
# Strip the Site URL off the item path, because Get-PnpFolderItem wants it
# to be relative to the site, not an absolute path.
$itemPath = $item.ServerRelativeUrl -replace "^$(([Uri]$item.Context.Url).AbsolutePath)/",''
# If this is a directory, recurse into this function.
# Otherwise, build target path and move file
if ($item -is [Microsoft.SharePoint.Client.Folder])
{
Move-FolderItemsRecursively $itemPath
}
else
{
$targetPath = Create-TargetPath -itemPath $itemPath -item $item
Move-CustomItem -SiteRelativeUrl $itemPath -targetPath $targetPath -item $item
}
}
}
比较 SharePoint Online 中的文件日期并移动文件
现在我们来到了最重要的部分,移动实际文件。在移动文件之前,我们需要检查文件是否存在于原始位置。如果是这样,我们需要比较文件日期,在这种情况下我们希望保留最后修改的文件。
# Move file to original folder
Function Move-CustomItem {
[CmdletBinding()]
param(
[parameter (Mandatory=$true)]
$siteRelativeUrl,
[parameter (Mandatory=$true)]
$targetPath,
[parameter (Mandatory=$true)]
$item
)
process
{
$moveFile = Compare-FileDates -sourceFilePath $siteRelativeUrl -targetFilePath $targetPath;
$global:moveLimitCounter++
if ($moveFile -eq $true)
{
if ($moveLimitCounter -eq $moveLimit)
{
Write-Warning 'Move limit reached'
exit;
}
if ($whatIf -ne $true)
{
# Move the file
Write-host ' - Move item to' $targetPath -BackgroundColor DarkYellow;
Move-PnPFile -SiteRelativeUrl $siteRelativeUrl -TargetUrl $targetPath -OverwriteIfAlreadyExists -Force:$force
Write-Host "`r`n"
}
else
{
Write-host ' - Move file from' $siteRelativeUrl -BackgroundColor DarkCyan
Write-host ' to' $targetPath -BackgroundColor DarkCyan
Write-Host "`r`n"
}
}
}
}
我在这里添加了一个计数器,用于计算移动的文件数量。当您要测试这样的脚本时,您可能只想先移动几个文件,然后在继续之前检查结果。
# Check if the file already exists in the target location
# If the file exists, we need to compare the dates to keep the latest files
Function Compare-FileDates ()
{
[CmdletBinding()]
param(
[parameter (Mandatory=$true)]
$targetFilePath,
[parameter (Mandatory=$true)]
$sourceFilePath
)
$targetFileExists = Get-PnPFile -Url $targetFilePath -ErrorAction SilentlyContinue
If($targetFileExists)
{
$sourceFile = Get-PnPFile -Url $sourceFilePath -AsListItem
$targetFile = Get-PnPFile -Url $targetFilePath -AsListItem
$sourceFileDate = Get-date $sourceFile['Modified']
$targetFileDate = Get-date $targetFile['Modified']
write-host ' - Comparing files dates: duplicate file: '$sourceFileDate 'original file: '$targetFileDate
# Check if the source file is newer then the target file
If ($sourceFile['Modified'] -gt $targetFile['Modified'])
{
write-host ' - Duplicate file is newer, move the file' -BackgroundColor DarkGreen
write-output $true
}
else
{
# Remove file
if ($whatIf -ne $true)
{
Write-host ' - Target file is newer. Removing duplicate file' -BackgroundColor DarkRed
Write-Host "`r`n"
Remove-PnPFile -SiteRelativeUrl $sourceFilePath -Recycle -Force:$force
}
else
{
Write-Host 'Remove file' $sourceFilePath -ForegroundColor Red
Write-Host "`r`n"
}
write-output $false
}
}
else
{
# Target file doesn't exists
Write-host ' - Target file does not exist' -BackgroundColor DarkGreen
Write-Output $true
}
}
因此,我们比较日期,如果原始文件较新,则我们删除重复的文件。在删除文件功能中,我添加了开关-Recycle,这样我们的文件就会被移动到回收站。如果您想永久删除文件,可以删除此开关。
总结
很高兴知道您的库中可能会出现一些空文件夹。我使用了一个单独的脚本,您可以运行它来清理空文件夹。您可以在我的 GitHub 上找到完整的脚本。
始终使用一些测试文件在测试 SharePoint 网站上测试这些类型的脚本。开始时,请确保将 whatif 设置为 $true
,将变量 force 设置为 $false
。
如果您有任何疑问,请在下面发表评论。
- 上一篇:[精彩网文] 为成功而努力
- 下一篇:[精彩网文] 为什么你需要一个明确的目标
猜你还喜欢
- 03-30 [玩转系统] 如何用批处理实现关机,注销,重启和锁定计算机
- 02-14 [系统故障] Win10下报错:该文件没有与之关联的应用来执行该操作
- 01-07 [系统问题] Win10--解决锁屏后会断网的问题
- 01-02 [系统技巧] Windows系统如何关闭防火墙保姆式教程,超详细
- 12-15 [玩转系统] 如何在 Windows 10 和 11 上允许多个 RDP 会话
- 12-15 [玩转系统] 查找 Exchange/Microsoft 365 中不活动(未使用)的通讯组列表
- 12-15 [玩转系统] 如何在 Windows 上安装远程服务器管理工具 (RSAT)
- 12-15 [玩转系统] 如何在 Windows 上重置组策略设置
- 12-15 [玩转系统] 如何获取计算机上的本地管理员列表?
- 12-15 [玩转系统] 在 Visual Studio Code 中连接到 MS SQL Server 数据库
- 12-15 [玩转系统] 如何降级 Windows Server 版本或许可证
- 12-15 [玩转系统] 如何允许非管理员用户在 Windows 中启动/停止服务
取消回复欢迎 你 发表评论:
- 精品推荐!
-
- 最新文章
- 热门文章
- 热评文章
[影视] 黑道中人 Alto Knights(2025)剧情 犯罪 历史 电影
[古装剧] [七侠五义][全75集][WEB-MP4/76G][国语无字][1080P][焦恩俊经典]
[实用软件] 虚拟手机号 电话 验证码 注册
[电视剧] 安眠书店/你 第五季 You Season 5 (2025) 【全10集】
[电视剧] 棋士(2025) 4K 1080P【全22集】悬疑 犯罪 王宝强 陈明昊
[软件合集] 25年6月5日 精选软件22个
[软件合集] 25年6月4日 精选软件36个
[短剧] 2025年06月04日 精选+付费短剧推荐33部
[短剧] 2025年06月03日 精选+付费短剧推荐25部
[软件合集] 25年6月3日 精选软件44个
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电视剧] 欢乐颂.5部全 (2016-2024)
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[影视] 【稀有资源】香港老片 艺坛照妖镜之96应召名册 (1996)
[剧集] 神经风云(2023)(完结).4K
[剧集] [BT] [TVB] [黑夜彩虹(2003)] [全21集] [粤语中字] [TV-RMVB]
[实用软件] 虚拟手机号 电话 验证码 注册
[资源] B站充电视频合集,包含多位重量级up主,全是大佬真金白银买来的~【99GB】
[影视] 内地绝版高清录像带 [mpg]
[书籍] 古今奇书禁书三教九流资料大合集 猎奇必备珍藏资源PDF版 1.14G
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电影] 美国队长4 4K原盘REMUX 杜比视界 内封简繁英双语字幕 49G
[电影] 死神来了(1-6)大合集!
[软件合集] 25年05月13日 精选软件16个
[精品软件] 25年05月15日 精选软件18个
[绝版资源] 南与北 第1-2季 合集 North and South (1985) /美国/豆瓣: 8.8[1080P][中文字幕]
[软件] 25年05月14日 精选软件57个
[短剧] 2025年05月14日 精选+付费短剧推荐39部
[短剧] 2025年05月15日 精选+付费短剧推荐36部
- 最新评论
-
- 热门tag