Búsqueda de sitios web

SharePoint Online: copiar una biblioteca de documentos usando PowerShell


Requisito: PowerShell para copiar una biblioteca de documentos en SharePoint Online.

¿Cómo copiar una biblioteca de documentos en SharePoint Online?

¿Alguna vez ha querido copiar una biblioteca de documentos en SharePoint Online? Quizás desee crear una nueva biblioteca con la misma estructura y contenido que una existente, o necesite duplicar el contenido de una biblioteca para fines de archivo o prueba. Cualquiera sea el motivo, es fácil de hacer. Este artículo le mostrará cómo usar PowerShell para copiar una biblioteca de documentos en el sitio de SharePoint Online.

No existen formas directas de copiar una biblioteca de documentos en SharePoint Online. Sin embargo, puede utilizar esta solución alternativa de plantilla de lista:

  1. Guarde la biblioteca de documentos de origen como plantilla: vaya a la biblioteca de origen >> Haga clic en el engranaje de Configuración >> Elija Configuración de la biblioteca >> Haga clic en “Guardar como plantilla”. Más información: ¿Cómo guardar la lista como plantilla en SharePoint Online?
  2. Cree una nueva biblioteca de documentos a partir de la plantilla de lista: Inicie sesión en su sitio de SharePoint Online >> Haga clic en el ícono de ajustes de Configuración y haga clic en "Agregar una aplicación". Puede usar la paginación en la parte inferior de la página para encontrar su plantilla de lista personalizada o usar el cuadro de búsqueda "Buscar una aplicación" y elegir su plantilla de lista. Más información: SharePoint Online: crear lista a partir de una plantilla personalizada usando PowerShell
  3. Copiar todos los elementos de la biblioteca de documentos de origen a la nueva biblioteca de documentos: Una vez que haya creado una nueva instancia de la biblioteca de documentos a partir de la plantilla de lista existente, puede copiar todos los archivos y carpetas de la biblioteca de origen a la biblioteca de destino seleccionando todos los elementos de la biblioteca de origen y elija el botón "Copiar a" en la barra de herramientas y luego especifique la biblioteca de documentos creada en el paso 2.

Automaticemos los pasos anteriores para copiar una biblioteca de documentos en SharePoint Online usando PowerShell:

Si desea copiar una biblioteca de documentos sin columnas de metadatos, simplemente puede crear una nueva biblioteca de documentos y usar la opción "Copiar a" de la barra de herramientas para copiar todos los archivos y carpetas a una nueva biblioteca.

¡Asegúrese de tener un script personalizado habilitado para la colección de sitios antes de continuar con este método! De lo contrario, terminará con un error de "Acceso denegado". ¿Cómo habilitar secuencias de comandos personalizadas en SharePoint Online?

SharePoint Online: PowerShell para copiar una biblioteca de documentos

PowerShell se puede utilizar para automatizar tareas y mejorar la eficiencia en su entorno de SharePoint Online. Déjame mostrarte cómo copiar una biblioteca de documentos usando PowerShell. Este script guarda la biblioteca de documentos de SharePoint Online existente como una plantilla, crea una nueva instancia a partir de ella y luego copia todos los archivos y carpetas de la biblioteca de documentos de origen a la nueva biblioteca.


#Parameters
$SiteURL = "https://crescent.sharepoint.com/sites/Retail"
$SourceLibraryName = "Invoices"
$DestinationLibraryName = "Invoices V1"
 
Try {
    #Connect to the Site
    Connect-PnPOnline -URL $SiteURL -Interactive
 
    #Get the Source library
    $SourceLibrary =  Get-PnPList -Identity $SourceLibraryName -Includes RootFolder
 
    #Get Timestamp
    $Timestamp = (Get-Date).tostring("yyyyMMdd-HHmmss")
    $TemplateName = $SourceLibrary.Title+"_"+$Timestamp

    #Step 1: Save the  Source Library as a template
    $SourceLibrary.SaveAsTemplate($TemplateName, $TemplateName, [string]::Empty, $False);
    Invoke-PnPQuery

    #Get the Library Template created
    $Ctx = Get-PnPContext
    $Web = Get-PnPWeb
    $RootWeb = $Ctx.Site.RootWeb
    $ListTemplates = $Ctx.Site.GetCustomListTemplates($RootWeb)
    $Ctx.Load($RootWeb)
    $Ctx.Load($ListTemplates)
    Invoke-PnPQuery
    $ListTemplate = $ListTemplates | Where {$_.Name -eq $TemplateName}
  
    #Step 2:  Create the destination library from the source library template
    If(!(Get-PnPList -Identity $DestinationLibraryName))
    {
        #Create the destination library
        $ListCreation = New-Object Microsoft.SharePoint.Client.ListCreationInformation
        $ListCreation.Title = $DestinationLibraryName
        $ListCreation.ListTemplate = $ListTemplate
        $DestinationList = $Web.Lists.Add($ListCreation)
        Invoke-PnPQuery
        Write-host "New Library '$DestinationLibraryName' created successfully!" -f Green
    }
    Else
    {
        Write-host "Library '$DestinationLibraryName' already exists!" -f Yellow
    }
    #Remove the List Template
    $TemplatePath = $Web.ServerRelativeUrl+"/_catalogs/lt/"+$ListTemplate.InternalName
    $TemplateFile = Get-PnPFile -Url $TemplatePath
    $TemplateFile.DeleteObject()
    Invoke-PnPQuery
    #Remove-PnPFile -ServerRelativeUrl $TemplatePath -Recycle -Force
 
    #Step 3: Copy content from Source to the destination library
    $DestinationLibrary = Get-PnPList $DestinationLibraryName -Includes RootFolder

    #Calculate Site Relative URL of the Folder
    If($Web.ServerRelativeURL -eq "/")
    {
	    $FolderSiteRelativeUrl = $SourceLibrary.RootFolder.ServerRelativeUrl
    }
    Else
    {      
	    $FolderSiteRelativeUrl = $SourceLibrary.RootFolder.ServerRelativeUrl.Replace($Web.ServerRelativeURL,[string]::Empty)
    }

    #Get All Content from Source Library's Root Folder
    $RootFolderItems = Get-PnPFolderItem -FolderSiteRelativeUrl $FolderSiteRelativeUrl | Where {($_.Name -ne "Forms") -and (-Not($_.Name.StartsWith("_")))}
        
    #Copy Items to the Destination
    $RootFolderItems | ForEach-Object {
        $DestinationURL = $DestinationLibrary.RootFolder.ServerRelativeUrl
        Copy-PnPFile -SourceUrl $_.ServerRelativeUrl -TargetUrl $DestinationURL -Force -OverwriteIfAlreadyExists
        Write-host "`tCopied '$($_.ServerRelativeUrl)'" -f Green    
    }    
}
Catch {
    write-host -f Red "Error:" $_.Exception.Message
}

Aunque el script anterior funciona bien para bibliotecas de documentos con <5000 elementos, en bibliotecas de documentos más grandes, el cmdlet PnP PowerShell Get-PnPFolderItem genera un error "Get-PnPFolderItem: el intento de operación está prohibido porque excede el umbral de vista de lista". Entonces, para mitigar ese problema, podemos reemplazar la parte de copia (de la línea 56 a la 74) con:


#Copy All Content from Source Library's Root Folder to the Destination Library
If($SourceLibrary.ItemCount -gt 0)
{
	#Get All Items from the Root Folder of the Library
	$global:counter = 0
	$ListItems = Get-PnPListItem -List $SourceLibraryName -PageSize 500 -Fields ID -ScriptBlock {Param($items) $global:counter += $items.Count; Write-Progress -PercentComplete `
		(($global:Counter / $SourceLibrary.ItemCount) * 100) -Activity "Getting Items from List" -Status "Getting Items $global:Counter of $($SourceLibrary.ItemCount)"}
	$RootFolderItems = $ListItems | Where { $_.FieldValues.FileRef.Replace(("/"+$_.FieldValues.FileLeafRef),[string]::Empty) -eq $SourceLibrary.RootFolder.ServerRelativeUrl}

	Write-Progress -Activity "Completed Getting Items from Library $($SourceLibrary.Title)" -Completed
	
	#Copy Items to the Destination
	$RootFolderItems | ForEach-Object {
		$DestinationURL = $DestinationLibrary.RootFolder.ServerRelativeUrl
		Copy-PnPFile -SourceUrl $_.FieldValues.FileRef -TargetUrl $DestinationURL -Force -OverwriteIfAlreadyExists
		Write-host "`tCopied $($_.FileSystemObjectType) '$DestinationURL'" -f Green    
	}
}

Copiar biblioteca de documentos con archivos, carpetas y metadatos

Puede copiar bibliotecas de documentos más grandes junto con sus archivos, carpetas y metadatos utilizando el siguiente script de PowerShell:


#Parameters
$SiteURL = "https://crescent.sharepoint.com/sites/Retail"
$SourceLibraryName = "Invoices"
$DestinationLibraryName = "Invoices V2"
 
Try {
    #Connect to the Site
    Connect-PnPOnline -URL $SiteURL -Interactive
 
    #Get the Source library
    $SourceLibrary =  Get-PnPList -Identity $SourceLibraryName -Includes RootFolder
 
    #Get Timestamp
    $Timestamp = (Get-Date).tostring("yyyyMMdd-HHmmss")
    $TemplateName = $SourceLibrary.Title+"_"+$Timestamp

    Write-host "Preparing Document Template..." -f Yellow -NoNewline
    #Step 1: Save the  Source Library as a template
    $SourceLibrary.SaveAsTemplate($TemplateName, $TemplateName, [string]::Empty, $False);
    Invoke-PnPQuery

    #Get the Library Template created
    $Ctx = Get-PnPContext
    $Web = Get-PnPWeb
    $RootWeb = $Ctx.Site.RootWeb
    $ListTemplates = $Ctx.Site.GetCustomListTemplates($RootWeb)
    $Ctx.Load($RootWeb)
    $Ctx.Load($ListTemplates)
    Invoke-PnPQuery
    $ListTemplate = $ListTemplates | Where {$_.Name -eq $TemplateName}
    Write-host "`tDone!" -f Green

    Write-host "Ensuring Document Library..." -f Yellow -NoNewline
    #Step 2:  Create the destination library from the source library template
    If(!(Get-PnPList -Identity $DestinationLibraryName))
    {
        #Create the destination library
        $ListCreation = New-Object Microsoft.SharePoint.Client.ListCreationInformation
        $ListCreation.Title = $DestinationLibraryName
        $ListCreation.ListTemplate = $ListTemplate
        $DestinationList = $Web.Lists.Add($ListCreation)
        Invoke-PnPQuery
        Write-host "New Library '$DestinationLibraryName' created successfully!" -f Green
    }
    Else
    {
        Write-host "Library '$DestinationLibraryName' already exists!" -f Yellow
    }
    #Remove the List Template
    $TemplatePath = $Web.ServerRelativeUrl+"/_catalogs/lt/"+$ListTemplate.InternalName
    $TemplateFile = Get-PnPFile -Url $TemplatePath
    $TemplateFile.DeleteObject()
    Invoke-PnPQuery
 
    Write-host "Copying Content Between Document Libraries..." -f Yellow
    #Step 3: Copy content from Source to the destination library
    $DestinationLibrary = Get-PnPList $DestinationLibraryName -Includes RootFolder

    #Copy All Content from Source Library's Root Folder to the Destination Library
    If($SourceLibrary.ItemCount -gt 0)
    {
        #Get All Items from the Root Folder of the Library
        $global:counter = 0
        $ListItems = Get-PnPListItem -List $SourceLibraryName -PageSize 500 -Fields ID -ScriptBlock {Param($items) $global:counter += $items.Count; Write-Progress -PercentComplete `
            (($global:Counter / $SourceLibrary.ItemCount) * 100) -Activity "Getting Items from List" -Status "Getting Items $global:Counter of $($SourceLibrary.ItemCount)"}
        $RootFolderItems = $ListItems | Where { $_.FieldValues.FileRef.Replace(("/"+$_.FieldValues.FileLeafRef),[string]::Empty) -eq $SourceLibrary.RootFolder.ServerRelativeUrl}
        Write-Progress -Activity "Completed Getting Items from Library $($SourceLibrary.Title)" -Completed
        
        #Copy Items to the Destination
        $RootFolderItems | ForEach-Object {
            $DestinationURL = $DestinationLibrary.RootFolder.ServerRelativeUrl
            Copy-PnPFile -SourceUrl $_.FieldValues.FileRef -TargetUrl $DestinationURL -Force -OverwriteIfAlreadyExists
            Write-host "`tCopied $($_.FileSystemObjectType) '$($_.FieldValues.FileRef)'" -f Green
        }

        Write-host "Copying Metadata Between Libraries..." -f Yellow -NoNewline
        #Get All Items from Destination Library
        $DestinationItems = Get-PnPListItem -List $DestinationLibraryName -PageSize 500
        
        #Copy Metadata
        ForEach($SourceItem in $ListItems)
        {
            #Get Metadata from Source Items
	        $Metadata = @{
		        'Title' = $SourceItem.FieldValues.Title
		        'Created'= $SourceItem.FieldValues.Created.DateTime
		        'Modified' = $SourceItem.FieldValues.Modified.DateTime
		        'Author' = $SourceItem.FieldValues.Author.Email
		        'Editor' = $SourceItem.FieldValues.Editor.Email
		        }

	        #Update Metadata in the destination Items
            $SourceItemServerRelativeURL = $SourceItem.FieldValues.FileLeafRef
            $DestinationItemServerRelativeURL = $SourceItem.FieldValues.FileLeafRef.Replace($SourceLibrary.RootFolder.ServerRelativeUrl,$DestinationLibrary.RootFolder.ServerRelativeUrl)
	        $MatchingItem = $DestinationItems | Where {$_.FieldValues.FileLeafRef -eq $DestinationItemServerRelativeURL}
            Set-PnPListItem -List $DestinationLibrary -Identity $MatchingItem.Id -Values $Metadata | Out-Null
        }
        Write-host "`tDone!" -f Green
    }
}
Catch {
    write-host -f Red "Error:" $_.Exception.Message
}

Este método de PowerShell conserva todos los metadatos excepto las marcas de tiempo creadas/modificadas y los valores de campo creados y modificados por. Para copiar una biblioteca de documentos a otro sitio, use: ¿Cómo copiar una biblioteca de documentos a otro sitio en SharePoint Online usando PowerShell?

Artículos relacionados