当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 如何存档 SharePoint Online?

作者:精品下载站 日期:2024-12-14 03:44:09 浏览:15 分类:玩电脑

如何存档 SharePoint Online?


SharePoint Online 是存储和共享文件、项目协作以及与团队成员沟通的绝佳工具。但是,随着 SharePoint Online 中存储的数据量的增长,您可能会耗尽存储空间。

您可以在 SharePoint Online 中购买额外的存储空间,这可能会变得相当昂贵。另一种选择是存档旧的 SharePoint 网站,但是您有什么选择呢?

在本文中,我们将了解归档 SharePoint 的不同选项。包括将数据传输到本地存储解决方案(例如 NAS)、Azure blob 存储以及 Microsoft Sentex 即将推出的新功能。

归档 SharePoint

尽管 SharePoint Online 附带大量存储空间,但多年来,您会发现随着公司的发展,大多数组织都会耗尽存储空间。原因之一是 SharePoint Online 中默认执行的版本控制。 SharePoint 将保留最多 500 个文件副本(版本)。根据文件类型和大小,这可能会占用大量存储空间。

笔记

在本文中阅读有关 SharePoint Online 存储的更多信息。

您可以购买额外的存储空间,但由于每月每 GB 0.20 美元的价格,账单很快就会变得很高。这就是为什么许多公司正在寻找归档 SharePoint Online 的选项。

微软已经发布了 Microsoft 365 Archive,它仍处于预览阶段,但您已经可以对其进行测试。存档 SharePoint 网站的其他选项包括:

  • 将数据下载到本地存储选项
  • 将数据移动到 Azure blob
  • 使用第三方备份解决方案

在搜索 SharePoint 归档解决方案时,通常会提到另外两个选项。设置保留策略是其中之一,但我认为这不是归档。例如,保留策略将简单地删除一年以上未使用的文件。

另一种选择是将数据移动到专用用户的 OneDrive 帐户。 OneDrive 为您提供 5TB 存储空间,因此这可能是某些人的选择。但请记住,OneDrive 的设计目的并不是让许多用户轻松访问,而且它也可能违反 Microsoft 服务协议。

将 SharePoint 存档到本地存储 (NAS)

将数据移动到本地存储选项(例如 NAS)通常是存档 SharePoint 的良好且经济实惠的解决方案。本地存储的优点是每5到7年只需一次投资,并且可以扩展。

但它也有一个经常被遗忘的缺点。如果您在办公室放置了 NAS 来保存已存档的 SharePoint 数据,请确保您还拥有该存储的备份。您不会是第一个 NAS 崩溃并丢失所有数据的人。

建议

我个人使用 Synology RS822+ 作为主 NAS,并使用较小的 DS220+ 作为 RS822+ 的备份。

在现代 SharePoint 库中,您只需选择文档库中的所有文件,然后单击下载按钮即可下载所有文件。不过,您必须对每个文档库执行此操作,但这是将文件存档到另一个存储解决方案的最简单方法。

[玩转系统] 如何存档 SharePoint Online?

如果您需要归档大量文件和文档库,那么更好的解决方案是使用 PowerShell 脚本。下面将从给定的 SharePoint 站点下载所有文档库并将文件下载到给定的路径。它基于 SharePointDairy.com 的脚本,但我已使用排除项扩展了该脚本,并向其中添加了日志记录。

Get-DocLibraries 函数中定义的排除列表会过滤掉站点页面、资产、保留库以及其他我们不需要的内容。您可以从我的 GitHub 存储库获取该脚本的最新版本。

文章在脚本下方继续

<#
.Synopsis
  Download all libaries, folders and files from SPO.

.DESCRIPTION
  Script is based on https://www.sharepointdiary.com/2017/07/download-all-files-from-sharepoint-site.html from Salaudeen.

  Script copies all document libraries including all content from SharePoint Online (SPO) to a local folder. Logging is 
  done through a log file, path for log file can be set.

  You can re-run the script, it will check if local files exists. If the file on SPO is newer, then it will update the local file.

  Scripts counts the number of files copied and skipped.

.NOTES
  Name: Copy-SpSiteToNAS.ps1
  Author: R. Mens
          S. Rajack
  Version: 1.1
  DateCreated:  2022
  Purpose/Change: init

.LINK
  a-d.site

[CmdletBinding(DefaultParameterSetName="Default")]
param(
  [Parameter(
    Mandatory = $true,
    HelpMessage = "SharePoint Site Url"
    )]
  [string]$siteUrl,

  [Parameter(
    Mandatory = $true,
    HelpMessage = "Enter path where to download files to"
    )]
  [string]$downloadPath,

  [Parameter(
    Mandatory = $false,
    HelpMessage = "Enter path for log file location"
    )]
  [string]$logFilePath = "c:\temp\sp-archive.txt",

  [Parameter(
    Mandatory = $false,
    HelpMessage = "Set log level"
  )]
  [ValidateSet("error", "warn", "info", "full")]
  [string]$logLevel = "full"
)
# Init Log file
$Global:logFile = [string]""
$Global:filesCopied = [int] 0
$Global:filesSkipped = [int] 0

Function Write-Log {
  <#
    .SYNOPSIS
    Save output in log file
  #>
  param(
      [Parameter(Mandatory = $true)][string] $message,
      [Parameter(Mandatory = $false)]
      [ValidateSet("FULL","INFO","WARN","ERROR")]
      [string] $level = "INFO"
  )
  
  # Create timestamp
  $timestamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss")

  if ($logLevel -eq 'warn') {
    $allowedLevels = @(
      'warn',
      'error'
    )
  }elseif ($loglevel -eq 'info') {
    $allowedLevels = @(
      'info',
      'warn',
      'error'
    )
  }elseif ($loglevel -eq 'full') {
    $allowedLevels = @(
      'full',
      'info',
      'warn',
      'error'
    )
  }
  # Output errors also to console
  if ($allowedLevels -contains $level) {
    # Append content to log file
    Add-Content -Path $Global:logFile -Value "$timestamp [$level] - $message"
  }

  # Output errors also to console
  if ($level -eq 'ERROR') {
    Write-host $message -ForegroundColor red
  }
}

Function Get-DocLibraries {
  <#
    .SYNOPSIS
    Get all document libraries from the SharePoint site, except excluded ones
  #>

  #Excluded libraries
  $ExcludedLists = @(
    "FormServerTemplates", 
    "Images",
    "Pages", 
    "PreservationHoldlibrary",
    "SiteAssets", 
    "SitePages", 
    "Style_x0020_library"
  )

  Get-PnPList -Includes RootFolder | Where-Object {$_.BaseType -eq "Documentlibrary" -and $_.EntityTypeName -notin $ExcludedLists -and $_.Hidden -eq $False}
}

Function Get-SPOFiles {
  <#
  .SYNOPSIS
    List all folders and files from the given library
  #>
  param(
    [Parameter(Mandatory = $true)] $List
  )
  process{
    Try {
      # Get all Items from the library - with progress bar
      $global:itemCounter = 0

      Get-PnPListItem -List $List -PageSize 1000 -Fields ID -ScriptBlock { 
        Param($items) 
        $global:itemCounter += $items.Count;

        # Create progress bar
        $getItemsProgress = @{
          Activity         = "Get items from $($List.Title)"
          Status           = "Progress->"
          PercentComplete  = ($global:itemCounter/$list.itemCount) * 100
          CurrentOperation = "$($items.Count) of $($list.itemCount)"
        }
        Write-Progress @getItemsProgress
      } 
       
      Write-Progress -Activity "Completed gettings items from library $($List.Title)" -Completed
    }Catch{
      Write-Log -Message "Error Downloading library $($List.Title) : $($_.Exception.Message)" -level ERROR
    }
  }
}

Function Copy-SPOFiles(){
  <#
  .SYNOPSIS
    Download all folders and files from the given library
  #>
  param(
    [Parameter(Mandatory = $true)] $ListItems,
    [Parameter(Mandatory = $true)] $List,
    [Parameter(Mandatory = $true)] $localFolder
  )
  process{
    Try {
      # Create a Local Folder for the Document library, if it doesn't exist
      $libraryFolder = $localFolder +"\" +$List.RootFolder.Name

      If (!(Test-Path -Path $libraryFolder)) {
        New-Item -ItemType Directory -Path $libraryFolder | Out-Null
      }

      # Get all Subfolders of the library
      $SubFolders = $ListItems | Where {$_.FileSystemObjectType -eq "Folder" -and $_.FieldValues.FileLeafRef -ne "Forms"}
      $SubFolders | ForEach-Object {
          # Create local path for the sub folder
          $LocalFolderPath = $localFolder + ($_.FieldValues.FileRef.Substring($Web.ServerRelativeUrl.Length)) -replace "/","\"
          
          # Create Local Folder, if it doesn't exist
          If (!(Test-Path -Path $LocalFolderPath)) {
                  New-Item -ItemType Directory -Path $LocalFolderPath | Out-Null
          }
          Write-Log -Message "Created subfolder $LocalFolderPath" -level FULL
      }

      # Get all Files from the folder
      $FilesColl =  $ListItems | Where {$_.FileSystemObjectType -eq "File"}
      $FileCounter = 0

      # Iterate through each file and download
      $FilesColl | ForEach-Object {

          # Frame the Parameters to download file
          $FileDownloadPath = ($localFolder + ($_.FieldValues.FileRef.Substring($Web.ServerRelativeUrl.Length)) -replace "/","\").Replace($_.FieldValues.FileLeafRef,'')
          
          $FileName = $_.FieldValues.FileLeafRef
          $SourceURL = $_.FieldValues.FileRef
          $FileModifiedDate = $_.FieldValues.Modified

          # Creating progressbar
          $FileCounter += 1;

          $downloadItemsProgress = @{
            Activity         = "Downloading items from $($List.Title)"
            Status           = "Progress->"
            PercentComplete  = ($FileCounter/$FilesColl.Count) * 100
            CurrentOperation = $FileName
          }
          Write-Progress @downloadItemsProgress

          #Check File Exists
          $FilePath = Join-Path -Path $FileDownloadPath -ChildPath $_.FieldValues.FileLeafRef

          If (-not(Test-Path -Path $FilePath -PathType Leaf)) {
            # Download the File
            Get-PnPFile -ServerRelativeUrl $SourceURL -Path $FileDownloadPath -FileName $FileName -AsFile -force
            Write-Log -Message "Downloaded $FileName from $SourceUrl " -level FULL
            $Global:filesCopied++
          }else{
            # Compare local and SPO file date
            if ($FileModifiedDate -gt ( Get-ChildItem -Path $FilePath | Select -ExpandProperty LastWriteTime)) {
              # SPO file is newer than local file, overwrite local file
              Get-PnPFile -ServerRelativeUrl $SourceURL -Path $FileDownloadPath -FileName $FileName -AsFile -force
              Write-Log -Message "Downloaded newer version of $FileName from $SourceUrl " -level FULL
              $Global:filesCopied++
            }else{
              Write-Log -Message "Skipped $FileName from $SourceUrl - Already exists" -level FULL
              $Global:filesSkipped++
            }
          }
      }
      Write-Progress -CurrentOperation "downloadItems" -Activity "Completed downloading items from library $($List.Title)" -Completed
    }
    Catch {
      Write-Log -Message "Error Downloading library $($List.Title) : $($_.Exception.Message)" -level ERROR
    }
  }
}

Function Get-NrOfDownloadedFiles() {
  <#
  .SYNOPSIS
    Download all folders and files from the given library
  #>
  param(
    [Parameter(Mandatory = $true)] $localFolder,
    [Parameter(Mandatory = $true)] $List
  )
  Process {
    $libraryFolder = $localFolder +"\" +$List.RootFolder.Name

    If (Test-Path -Path $libraryFolder) {
      (Get-ChildItem -Path $libraryFolder -File -Recurse).count
    }
  }
}

Function New-SPSiteArchiveFolder() {
  <#
  .SYNOPSIS
    Download all folders and files from the given library
  #>
  param(
    [Parameter(Mandatory = $true)] $title,
    [Parameter(Mandatory = $true)] $downloadPath
  )
  process {
    If (!(Test-Path -Path ($downloadPath +"\" +$title))) {
      New-Item -Path $downloadPath -Name $title -ItemType 'directory'
    }Else{
      $downloadPath +"\" +$title
    }
  }
}

# Connect to SharePoint Online
Connect-PnPOnline $SiteURL -Interactive
$Web = Get-PnPWeb
 
# Create Log file
$Global:logFile = $logFilePath + "\" + $Web.title + ".txt"
New-Item -Path $Global:logFile -Force | Out-Null

# Create folder for SharePoint site in Archive folder
$localFolder = New-SPSiteArchiveFolder -DownloadPath $downloadPath -title $web.title

# Get all the libraries
$documentLibraries = Get-DocLibraries
Write-Log -Message  "$(($documentLibraries).count) Document Libraries found" -level INFO

# Download all the files from each library if they contain items
ForEach($library in $documentLibraries)
{
  if ($library.itemCount -ne 0) {
    Write-Log -Message "Process document library : $($library.title)" -level INFO
    
    # Count nr of files in the doc library
    $SPOItems = Get-SPOFiles -List $library
    Write-Log -Message "$($SPOItems.count) files and folders found in $($library.title)" -level INFO
    
    # Download the files
    Copy-SPOFiles -List $library -ListItems $SPOItems -localFolder $localFolder

    # Count files in the local folder
    $CountLocalItems = Get-NrOfDownloadedFiles -List $library -localFolder $localFolder
    Write-Log -Message "$CountLocalItems files downloaded to the local folder" -level INFO
  }else{
    Write-Log -Message "Skipping document library : $($library.title) - No files found" -level WARN
  }
}

Write-Log -Message "---------------------------------------------" -level INFO
Write-Log -Message "Download completed" -level INFO
Write-Log -Message "---------------------------------------------" -level INFO
Write-Log -Message "Number of files copied $($Global:filesCopied)" -level INFO
Write-Log -Message "Number of files skipped $($Global:filesSkipped)" -level INFO
Write-Log -Message "---------------------------------------------" -level INFO

将 SharePoint 归档到 Azure Blob

Azure Blob 存储具有不同的访问层,每个访问层都有自己的价格、性能和可用性。使用云存储,您不仅需要为您使用的实际存储空间付费,还需要为每个写入和读取事务付费。

创建新的 Azure 存储帐户时,有四个级别可供选择。高级层与 SharePoint Online 几乎相同,只是其成本比 SharePoint 存储低几美分(每 Gb 0.15 美元)。因此,对于归档,我们实际上有三个层次可供选择:

Hot tierCool tierArchive tierAvailability99.9%99%OfflineRecommended data
retention periodNone30 Days180 daysAccess LatencyMillisecondsMillisecondsHoursUsage chargesHigher storage costs, but lower access and transaction costsLower storage costs, but higher access and transaction costsLowest storage costs, but highest access, and transaction costsPrice per Gb
(first 50TB)$0.018per GB$0.01per GB$0.00099per GB

我认为热层和冷层是归档的最佳选择。在我看来,归档层更适合用于备份目的。

设置 Azure 存储帐户

第一步是设置 Azure 存储帐户。您可以先注册一个免费帐户,这将为您提供高达 200 美元的 Azure 资源。之后,您随时可以决定是否继续。

  1. 打开 Azure 门户并单击或搜索存储帐户
  2. 创建新的存储帐户
  3. 选择您要使用的订阅
  4. 创建一个新资源组,将其命名为Archive
  5. 输入唯一的存储帐户名称(在 Azure 中必须是唯一的!)
  6. 选择存储数据的区域
  7. 单击下一步:高级

[玩转系统] 如何存档 SharePoint Online?

在高级页面上,您可以选择要使用的访问层。您需要向下滚动一点到 Blob 存储。默认情况下,选择“热门”层:

[玩转系统] 如何存档 SharePoint Online?

查看“数据保护”选项卡也是个好主意。您可以在此处配置删除文件和容器后在 Azure 中保留的时间。

完成后,单击审核选项卡。如果没有错误,请单击创建

创建文件共享

我们需要能够从 PowerShell 脚本中访问这些文件。为此,我们将创建一个新的文件共享。这使我们能够在资源管理器中打开并安装 Azure Blob 存储,并将其用作脚本的下载路径。

创建文件共享时,您需要选择层。该层决定性能以及从共享上传和下载文件的成本。最好从事务优化层开始,并在所有文件归档后将其更改为冷层。

[玩转系统] 如何存档 SharePoint Online?

在 Windows 中连接文件共享

创建文件共享后,将其打开并单击连接。在这里我们可以选择要使用的驱动器号和身份验证方法。默认情况下,使用存储帐户。

[玩转系统] 如何存档 SharePoint Online?

选择驱动器号后,单击“显示脚本”。这将为您提供一个 PowerShell 脚本,您可以运行该脚本以在资源管理器中挂载 Azure 文件共享:

[玩转系统] 如何存档 SharePoint Online?

将 SharePoint 存档到 Azure Blob

创建并安装 Azure Blob 存储后,我们现在可以使用本文开头的 PowerShell 脚本将文件从 SharePoint 移动到 Azure。请记住,此方法将通过您的互联网连接下载和上传所有文件。

.\Copy-SpSiteToNAS.ps1 -siteUrl https://lazydev.sharepoint.com/sites/lab28 -downloadPath a:\

[玩转系统] 如何存档 SharePoint Online?

该脚本需要一些时间,但所有文件最终都会上传到 Azure Blob 存储。验证所有文件均已复制后,您可以从 SharePoint 中删除数据。

笔记

我认为还应该可以在 Azure Runbook 中运行 PowerShell 脚本。但这是我稍后会锻炼的。

第三方备份解决方案

使用第三方备份解决方案也是存档 SharePoint 的一种方法。许多备份提供商都提供无限保留,有些甚至提供无限存储。因此,根据数据量和用户数量,这有时是一个可行的解决方案。

使用第三方备份解决方案进行归档还有另一个优势,您还拥有适用于 Microsoft 365 数据的主动备份解决方案。 SharePoint 仅保留您的数据 93 天,之后您将无法再恢复它们。

但这也有一个缺点。如果您已从 SharePoint 中删除数据(这就是归档的目的),那么从备份提供程序切换将是一项艰巨的任务。这意味着您需要从备份提供商恢复所有存档数据,然后再次将其存档/备份到另一个提供商。

这是你真正需要牢记的事情。您现在可能认为您不会很快切换,但如果提供商提高价格,那么该解决方案可能会比购买额外的 SharePoint 存储更昂贵。

微软语法

在 2022 年 10 月的 Microsoft Ignite 活动期间,微软宣布将为 SharePoint 和 Microsoft Teams 引入 Syntex 归档。 Syntex Archiving 将为 SharePoint 添加分层存储,使我们能够将不太重要的内容(或旧内容)转移到成本较低的存储中。

笔记

Microsoft 发布了 Microsoft 365 Archive,它是 Syntex 的一部分。您可以在本文中阅读有关此新功能的更多信息。

Microsoft Syntex 不仅提供归档功能,还可以帮助您增强内容、理解和构建信息以及简化工作流程。您可以在 Microsoft 的这篇文章中阅读有关 Syntex 的更多信息。

目前 Syntex 的费用为每个用户每月 5 美元。我认为这个价格不包含存储,因此这可能也是额外的成本,类似于 Azure 存储层。

现在每个用户 5 美元可能看起来有点多,但如果你读过这篇文章,那么你还会发现它在今年晚些时候附带了备份和恢复功能。这意味着您不再需要第三方备份解决方案。

总结

归档 SharePoint 是我们迟早都需要做的事情。随着我们的数据增长,管理将变得更加困难,并且存储成本只会增加。我更喜欢将 SharePoint 存档到 Azure Blob,因为这样您仍然可以将所有数据保存在云中,而无需承担保护本地存储数据的负担。

Microsoft Syntex 可能会成为归档和备份的一个非常有趣的选择。请确保您订阅下面的时事通讯以了解最新信息。

我希望这篇文章对您归档 SharePoint 有所帮助,如果您有任何疑问,请在下面发表评论。

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯