¿Cómo archivar SharePoint Online?
SharePoint Online es una gran herramienta para almacenar y compartir archivos, colaborar en proyectos y comunicarse con los miembros del equipo. Sin embargo, a medida que crece la cantidad de datos almacenados en SharePoint Online, probablemente se quedará sin espacio de almacenamiento.
Puede comprar almacenamiento adicional en SharePoint Online, lo que puede resultar bastante caro. La otra opción sería archivar sitios antiguos de SharePoint, pero ¿qué opciones tienes para eso?
En este artículo, veremos las diferentes opciones para archivar SharePoint. Incluyendo la transferencia de datos a una solución de almacenamiento local (NAS, por ejemplo), almacenamiento de blobs de Azure y veremos las próximas características nuevas de Microsoft Sentex.
Archivar SharePoint
Aunque SharePoint online viene con una gran cantidad de espacio de almacenamiento, con el paso de los años verá que la mayoría de las organizaciones se quedan sin almacenamiento a medida que la empresa crece. Una de las razones es el control de versiones que se realiza de forma predeterminada en SharePoint Online. SharePoint retendrá hasta 500 copias (versiones) de un archivo. Dependiendo del tipo y tamaño del archivo, esto puede consumir mucho espacio de almacenamiento.
Nota
Lea más sobre el almacenamiento de SharePoint Online en este artículo.
Es posible comprar almacenamiento adicional, pero con un precio de 0,20 dólares por GB al mes, la factura puede aumentar bastante rápidamente. Es por eso que muchas empresas están buscando opciones para archivar SharePoint Online.
Microsoft lanzó Microsoft 365 Archive, todavía está en Vista previa, pero ya puedes probarlo. Otras opciones para archivar sus sitios de SharePoint son:
- Descargar datos a una opción de almacenamiento local
- Mover datos a un blob de Azure
- Utilice una solución de copia de seguridad de terceros
Hay otras dos opciones que a menudo se mencionan cuando se buscan soluciones de archivo para SharePoint. Configurar políticas de retención es una de ellas, pero en mi opinión eso no es archivar. La política de retención simplemente eliminará los archivos que no se utilicen durante más de un año, por ejemplo.
La otra opción es mover los datos a una cuenta OneDrive de un usuario dedicado. OneDrive te ofrece 5 TB de almacenamiento, por lo que podría ser una opción para algunos. Pero tenga en cuenta que OneDrive no está diseñado para que muchos usuarios puedan acceder fácilmente a él y también podría ir en contra del Acuerdo de servicio de Microsoft.
Archivar SharePoint en almacenamiento local (NAS)
Mover los datos a una opción de almacenamiento local, por ejemplo, un NAS, suele ser una solución buena y asequible para archivar SharePoint. La ventaja del almacenamiento local es que solo requiere una inversión única cada 5 a 7 años y se expandirá.
Pero también tiene un inconveniente que a menudo se olvida. Si coloca un NAS en su oficina con sus datos archivados de SharePoint, asegúrese de tener también una copia de seguridad de ese almacenamiento. No serás el primero en el que el NAS falla y pierdes todos los datos.
Consejo
Personalmente uso un Synology RS822+ como NAS principal y uso un DS220+ más pequeño como respaldo del RS822+.
En las bibliotecas modernas de SharePoint, simplemente puede seleccionar todos los archivos en la biblioteca de documentos y presionar el botón de descarga para descargar todos los archivos. Sin embargo, tendrá que hacer esto por biblioteca de documentos, pero esta es la forma más sencilla de archivar los archivos en otra solución de almacenamiento.
Si necesita archivar muchos archivos y bibliotecas de documentos, una mejor solución es utilizar un script de PowerShell para ello. Lo siguiente descargará todas las bibliotecas de documentos del sitio de SharePoint indicado y descargará los archivos a la ruta indicada. Está basado en un script de SharePointDairy.com, pero lo amplié con exclusiones y le agregué el registro.
La lista de exclusión, definida en la función Get-DocLibraries, filtra las páginas del sitio, los recursos, las bibliotecas de conservación y otros que no necesitamos. Puede obtener la última versión del script aquí desde mi repositorio de GitHub.
El artículo continúa debajo del guión
<#
.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 INFOArchivar SharePoint en Azure Blob
Azure Blob Storage viene en diferentes niveles de acceso, cada uno con su propio precio, rendimiento y disponibilidad. Con el almacenamiento en la nube, no solo paga por el espacio de almacenamiento real que utiliza, sino que también deberá pagar por cada transacción de escritura y lectura.
Hay cuatro niveles para elegir al crear una nueva cuenta de Azure Storage. El nivel premium es prácticamente el mismo que SharePoint Online, sólo que cuesta unos centavos menos ($0,15 por Gb) que el almacenamiento de SharePoint. Entonces, para archivar tenemos tres niveles para elegir:
| Hot tier | Cool tier | Archive tier | |
|---|---|---|---|
| Availability | 99.9% | 99% | Offline |
| Recommended data retention period | None | 30 Days | 180 days |
| Access Latency | Milliseconds | Milliseconds | Hours |
| Usage charges | Higher storage costs, but lower access and transaction costs | Lower storage costs, but higher access and transaction costs | Lowest storage costs, but highest access, and transaction costs |
| Price per Gb (first 50TB) | $0.018 per GB | $0.01 per GB | $0.00099 per GB |
En mi opinión, el nivel Hot y el nivel Cool son la mejor opción para archivar. El nivel de archivo me parece más adecuado para fines de copia de seguridad.
Configurar una cuenta de almacenamiento de Azure
El primer paso es configurar la cuenta de Azure Storage. Primero puede registrarse para obtener una cuenta gratuita, que le brindará hasta $200 en recursos de Azure. Después de eso, siempre podrás decidir si quieres continuar o no.
- Abra el Portal de Azure y haga clic o busque Cuentas de almacenamiento.
- Cree una nueva cuenta de almacenamiento
- Selecciona la suscripción que deseas utilizar
- Cree un nuevo grupo de recursos y asígnele el nombre Archivo.
- Introduzca un nombre de cuenta de almacenamiento único (¡debe ser único en Azure!)
- Seleccione la región donde almacenar los datos
- Haga clic en Siguiente: Avanzado
En la página avanzada, puede seleccionar el nivel de acceso que desea utilizar. Deberá desplazarse un poco hacia abajo hasta Blob Storage. De forma predeterminada, el nivel Hot está seleccionado:
También es una buena idea consultar la pestaña Protección de datos. Aquí puede configurar cuánto tiempo desea conservar los archivos y contenedores en Azure después de su eliminación.
Cuando haya terminado, haga clic en la pestaña Revisar . Si no hay errores, haga clic en Crear.
Crear un archivo compartido
Necesitaremos poder acceder a los archivos desde nuestro script de PowerShell. Para hacer esto vamos a crear un nuevo archivo compartido. Esto nos permite abrir y montar el almacenamiento de blobs de Azure en nuestro explorador y usarlo como ruta de descarga para nuestro script.
Al crear un recurso compartido de archivos, deberá seleccionar el nivel. Este nivel determina el rendimiento y también el costo de cargar y descargar archivos del recurso compartido. Es mejor comenzar con el nivel optimizado para transacciones y cambiarlo al nivel Cool una vez que se hayan archivado todos los archivos.
Conexión del recurso compartido de archivos en Windows
Una vez que haya creado el archivo compartido, ábralo y haga clic en Conectar. Aquí podemos seleccionar la letra de unidad que queremos usar y el método de autenticación. De forma predeterminada, se utiliza la cuenta de almacenamiento.
Después de haber seleccionado la letra de la unidad, haga clic en Mostrar secuencia de comandos. Esto le proporcionará un script de PowerShell que puede ejecutar para montar el recurso compartido de archivos de Azure en su Explorador:
Archivar SharePoint en Azure Blob
Con Azure Blob Storage creado y montado, ahora podemos usar el script de PowerShell, del principio de este artículo, para mover los archivos de SharePoint a Azure. Sin embargo, tenga en cuenta que este método descargará y cargará todos los archivos a través de su conexión a Internet.
.\Copy-SpSiteToNAS.ps1 -siteUrl https://lazydev.sharepoint.com/sites/lab28 -downloadPath a:\La secuencia de comandos lleva algún tiempo, pero todos los archivos finalmente se cargan en Azure Blob Storage. Una vez que haya verificado que todos los archivos estén copiados, puede eliminar los datos de SharePoint.
Nota
Creo que también debería ser posible ejecutar el script de PowerShell dentro de un Runbook de Azure. Pero eso es algo que practicaré más adelante.
Solución de copia de seguridad de terceros
Usar una solución de respaldo de terceros también es una forma de archivar SharePoint. Muchos proveedores de respaldo vienen con retención ilimitada y algunos incluso con almacenamiento ilimitado. Entonces, dependiendo de la cantidad de datos y la cantidad de usuarios, esta a veces puede ser una solución viable.
El uso de una solución de respaldo de terceros para archivar tiene otra ventaja: también tiene una solución de respaldo activa para sus datos de Microsoft 365. SharePoint sólo conserva sus datos durante 93 días, después de los cuales ya no podrá restaurarlos.
Pero esto también tiene una desventaja. Si ha eliminado los datos de SharePoint, que es el propósito aquí con el archivado, cambiar del proveedor de respaldo será una tarea horrible. Significa que necesitará restaurar todos los datos archivados del proveedor de respaldo y luego archivarlos/hacer una copia de seguridad nuevamente en otro proveedor.
Esto es algo que realmente debes tener en cuenta. Ahora podría pensar que no cambiará tan pronto, pero si el proveedor aumenta los precios, la solución podría resultar incluso más costosa que comprar almacenamiento adicional de SharePoint.
Microsoft Syntex
Durante el evento Microsoft Ignite de octubre de 2022, Microsoft anunció que introducirá el archivo Syntex para SharePoint y Microsoft Teams. Syntex Archiving agregará almacenamiento por niveles a SharePoint y nos permitirá mover contenido menos crítico (o antiguo) a un almacenamiento de menor costo.
Nota
Microsoft ha lanzado Microsoft 365 Archive, que forma parte de Syntex. Puede leer más sobre esta nueva característica en este artículo.
Microsoft Syntex no solo ofrece funciones de archivo, sino que también le ayuda a mejorar su contenido, comprender y estructurar su información y simplificar los flujos de trabajo. Puede leer más sobre Syntex en este artículo de Microsoft.
Actualmente, Syntex cuesta 5 dólares por usuario al mes. No creo que el almacenamiento esté incluido en este precio, por lo que probablemente también sean costos adicionales, similares a los niveles de Azure Storage.
Ahora, $5 por usuario puede parecer un poco excesivo, pero si has leído el artículo, también verás que viene con una función de copia de seguridad y restauración a finales de este año. Esto significa que ya no necesitas una solución de respaldo de terceros.
Concluyendo
Archivar SharePoint es algo que todos debemos hacer tarde o temprano. A medida que nuestros datos crezcan, será más difícil gestionarlos y el coste de almacenamiento no hará más que aumentar. Prefiero archivar SharePoint en Azure Blob porque de esta manera todavía tienes todos tus datos en la nube y no tienes la carga de proteger los datos almacenados localmente.
Microsoft Syntex puede convertirse en una opción realmente interesante para archivar y realizar copias de seguridad. Asegúrese de suscribirse al boletín a continuación para mantenerse actualizado.
Espero que este artículo te haya ayudado a archivar SharePoint. Si tienes alguna pregunta, deja un comentario a continuación.






