Búsqueda de sitios web

SharePoint Online: copie elementos de la lista de una lista a otra usando PowerShell


Requisito: Copie los elementos de la lista a otra lista en SharePoint Online.

¿Cómo copiar elementos de una lista a otra lista en SharePoint Online?

¿Necesita copiar elementos de la lista de una lista a otra? Quizás necesites migrar datos de una lista antigua a una nueva. O tal vez simplemente necesite mover rápida y fácilmente algunos elementos entre listas. En cualquier caso, si está buscando una manera de copiar elementos de una lista de SharePoint Online a otra, le mostraremos cómo usar PowerShell para copiar elementos de la lista entre listas de SharePoint Online.

Utilice Edición rápida (vista Hoja de datos) para copiar y pegar elementos de lista entre listas en SharePoint Online. Asegúrese de tener columnas coincidentes y que el orden de las columnas sea el mismo en ambas vistas.

Importante: Antes de continuar con cualquiera de los scripts siguientes, asegúrese de haber clonado la lista existente (¡guarde la lista como plantilla!) y haya creado una nueva instancia de lista (sin datos). ¡Estos scripts solo copian datos, pero no crean una lista!

También puedes usar: ¿Cómo crear una nueva lista a partir de una lista existente en SharePoint Online?

SharePoint Online: copiar elemento de la lista a otra lista usando PowerShell

Puede utilizar este script de PowerShell cuando desee repetir la copia de elementos entre listas de SharePoint Online.


#Load SharePoint CSOM Assemblies
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"

Function Copy-ListItems()
{
    param
    (
        [Parameter(Mandatory=$true)] [string] $SiteURL,
        [Parameter(Mandatory=$true)] [string] $SourceListName,
        [Parameter(Mandatory=$true)] [string] $TargetListName
    )    
    Try {
        #Setup Credentials to connect
        $Cred = Get-Credential
        $Cred = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.UserName,$Cred.Password)
    
        #Setup the context
        $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
        $Ctx.Credentials = $Cred

        #Get the Source List and Target Lists
        $SourceList = $Ctx.Web.Lists.GetByTitle($SourceListName)
        $TargetList = $Ctx.Web.Lists.GetByTitle($TargetListName)
    
        #Get All Items from Source List
        $SourceListItems = $SourceList.GetItems([Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery())
        $Ctx.Load($SourceListItems)
        $Ctx.ExecuteQuery()
    
        #Get each column value from source list and add them to target
        ForEach($SourceItem in $SourceListItems)
        {
            $NewItem =New-Object Microsoft.SharePoint.Client.ListItemCreationInformation
            $ListItem = $TargetList.AddItem($NewItem)
        
            #Map each field from source list to target list - INTERNAL NAMES
            $ListItem["Title"] = $SourceItem["Title"]
            $ListItem["IsActive"] = $SourceItem["IsActive"]
            $ListItem["ProjectStartDate"] = $SourceItem["ProjectStartDate"]
            $ListItem["Department"] = $SourceItem["Department"]
            $ListItem["Priority"] = $SourceItem["Priority"]
            $ListItem.update()
        }
        $Ctx.ExecuteQuery()

        write-host  -f Green "Total List Items Copied from '$SourceListName' to '$TargetListName' : $($SourceListItems.count)"
    }
    Catch {
        write-host -f Red "Error Copying List Items!" $_.Exception.Message
    }
}

#Set Parameters
$SiteURL= "https://crescent.sharepoint.com/"
$SourceListName="Projects Template"
$TargetListName="Project Innovate"

#Call the function to copy list items
Copy-ListItems -siteURL $SiteURL -SourceListName $SourceListName -TargetListName $TargetListName

Este script copia todos los valores de las columnas asignadas desde el origen a la lista de destino. Mejoremos el bit del script para copiar automáticamente todas las columnas que coincidan desde la lista de origen a la de destino.

SharePoint Online: copiar elementos de la lista mediante PowerShell

En lugar de codificar cada campo, esta vez copiemos todos los valores de los campos entre listas:


#Load SharePoint CSOM Assemblies
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"

Function Copy-ListItems()
{
    param
    (
        [Parameter(Mandatory=$true)] [string] $SiteURL,
        [Parameter(Mandatory=$true)] [string] $SourceListName,
        [Parameter(Mandatory=$true)] [string] $TargetListName
    )    
    Try {
        #Setup Credentials to connect
        $Cred = Get-Credential
        $Cred = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.UserName,$Cred.Password)
    
        #Setup the context
        $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
        $Ctx.Credentials = $Cred

        #Get the Source List and Target Lists
        $SourceList = $Ctx.Web.Lists.GetByTitle($SourceListName)
        $TargetList = $Ctx.Web.Lists.GetByTitle($TargetListName)
    
        #Get All Items from Source List
        $SourceListItems = $SourceList.GetItems([Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery())
        $Ctx.Load($SourceListItems)
        $Ctx.ExecuteQuery()
    
        #Get All fields from Source List & Target List
        $SourceListFields = $SourceList.Fields
        $Ctx.Load($SourceListFields)
        $TargetListFields = $TargetList.Fields
        $Ctx.Load($TargetListFields)        
        $Ctx.ExecuteQuery()

        #Get each column value from source list and add them to target
        ForEach($SourceItem in $SourceListItems)
        {
            $NewItem =New-Object Microsoft.SharePoint.Client.ListItemCreationInformation
            $ListItem = $TargetList.AddItem($NewItem)        
 
            #Map each field from source list to target list
            Foreach($SourceField in $SourceListFields)
            {  
                #Skip Read only, hidden fields, content type and attachments
                If((-Not ($SourceField.ReadOnlyField)) -and (-Not ($SourceField.Hidden)) -and ($SourceField.InternalName -ne  "ContentType") -and ($SourceField.InternalName -ne  "Attachments") )  
                {
                    $TargetField = $TargetListFields | where { $_.Internalname -eq $SourceField.Internalname}
                    if($TargetField -ne $null)
                    {
                        #Copy column value from source to target
                        $ListItem[$TargetField.InternalName] = $SourceItem[$SourceField.InternalName]  
                    }
                }
            }
            $ListItem.update()
            $Ctx.ExecuteQuery()
        }

        write-host  -f Green "Total List Items Copied from '$SourceListName' to '$TargetListName' : $($SourceListItems.count)"
    }
    Catch {
        write-host -f Red "Error Copying List Items!" $_.Exception.Message
    }
}

#Set Parameters
$SiteURL= "https://crescent.sharepoint.com/"
$SourceListName="Projects Template"
$TargetListName="Project Innovate"

#Call the function to copy list items
Copy-ListItems -siteURL $SiteURL -SourceListName $SourceListName -TargetListName $TargetListName

PowerShell para copiar elementos de la lista con archivos adjuntos de una lista a otra

Copiemos elementos junto con los archivos adjuntos de una lista a otra en SharePoint Online usando PowerShell:


#Load SharePoint CSOM Assemblies
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"

Function Copy-ListItems()
{
    param
    (
        [Parameter(Mandatory=$true)] [string] $SiteURL,
        [Parameter(Mandatory=$true)] [string] $SourceListName,
        [Parameter(Mandatory=$true)] [string] $TargetListName
    )    
    Try {
        #Setup Credentials to connect
        $Cred = Get-Credential
        $Cred = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.UserName,$Cred.Password)
    
        #Setup the context
        $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
        $Ctx.Credentials = $Cred

        #Get the Source List and Target Lists
        $SourceList = $Ctx.Web.Lists.GetByTitle($SourceListName)
        $TargetList = $Ctx.Web.Lists.GetByTitle($TargetListName)
    
        #Get All Items from Source List
        $SourceListItems = $SourceList.GetItems([Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery())
        $Ctx.Load($SourceListItems)
        $Ctx.ExecuteQuery()
    
        Write-host "Total Number of List Items Found in the source:"$SourceListItems.count

        #Get All fields from Source List & Target List
        $SourceListFields = $SourceList.Fields
        $Ctx.Load($SourceListFields)
        $TargetListFields = $TargetList.Fields
        $Ctx.Load($TargetListFields)        
        $Ctx.ExecuteQuery()

        #Get each column value from source list and add them to target
        ForEach($SourceItem in $SourceListItems)
        {
            $NewItem =New-Object Microsoft.SharePoint.Client.ListItemCreationInformation
            $ListItem = $TargetList.AddItem($NewItem)        
 
            #Map each field from source list to target list
            Foreach($SourceField in $SourceListFields)
            {  
                #Skip Read only, hidden fields, content type and attachments
                If((-Not ($SourceField.ReadOnlyField)) -and (-Not ($SourceField.Hidden)) -and ($SourceField.InternalName -ne  "ContentType") -and ($SourceField.InternalName -ne  "Attachments") )  
                {
                    $TargetField = $TargetListFields | where { $_.Internalname -eq $SourceField.Internalname}
                    if($TargetField -ne $null)
                    {
                        #Copy column value from source to target
                        $ListItem[$TargetField.InternalName] = $SourceItem[$SourceField.InternalName]  
                    }
                }
            }
            
            $ListItem.update()
            $Ctx.ExecuteQuery()

            #Copy attachments
            $AttachmentsColl = $SourceItem.AttachmentFiles
            $Ctx.Load($AttachmentsColl)
            $Ctx.ExecuteQuery()

            ForEach($Attachment in $AttachmentsColl)
            {
                Write-host "Copying attachment '$($Attachment.FileName)' from Item ID '$($SourceItem.ID)'"
                #Get attachment File from Source List Item
                $File = $Ctx.Web.GetFileByServerRelativeUrl($Attachment.ServerRelativeUrl)
                $Ctx.Load($File)
                $Ctx.ExecuteQuery()

                #Get the Source File Content
                $FileContent = $File.OpenBinaryStream()
                $Ctx.ExecuteQuery()
                $Buffer = New-Object Byte[]($File.length)
                $BytesRead = $FileContent.Value.Read($Buffer, 0, $Buffer.Length)
                $MemoryStream = New-Object -TypeName System.IO.MemoryStream(,$Buffer)

                #Add Attachment to Target List Item
                $AttachmentCreation = New-Object Microsoft.SharePoint.Client.AttachmentCreationInformation
                $AttachmentCreation.ContentStream = $MemoryStream
                $AttachmentCreation.FileName = $Attachment.FileName 
                [void]$ListItem.AttachmentFiles.Add($AttachmentCreation)
                $Ctx.ExecuteQuery()
                $MemoryStream.Close()
            }
            Write-host "Copied Item to the Target List:"$SourceItem.id -f Yellow
        }

        write-host  -f Green "Total List Items Copied from '$SourceListName' to '$TargetListName' : $($SourceListItems.count)"
    }
    Catch {
        write-host -f Red "Error Copying List Items!" $_.Exception.Message
    }
}

#Set Parameters
$SiteURL= "https://crescent.sharepoint.com/"
$SourceListName="Projects"
$TargetListName="Project Temp"

#Call the function to copy list items
Copy-ListItems -siteURL $SiteURL -SourceListName $SourceListName -TargetListName $TargetListName

Aquí hay otra publicación para que SharePoint local copie un elemento de la lista: Copiar un elemento de la lista de SharePoint a otra lista usando PowerShell

PnP PowerShell para copiar elementos entre listas de SharePoint Online

Los scripts anteriores funcionan bien siempre y cuando los campos de la lista no sean selector de personas, búsqueda, metadatos administrados o hipervínculo. Aquí está el script para manejar todos los campos complejos y copiar elementos de la lista:


#Function to copy attachments between list items
Function Copy-SPOAttachments($SourceItem, $TargetItem)
{
    Try {
        #Get All Attachments from Source
        $Attachments = Get-PnPProperty -ClientObject $SourceItem -Property "AttachmentFiles"
        $Attachments | ForEach-Object {
        #Download the Attachment to Temp
        $File  = Get-PnPFile -Url $_.ServerRelativeUrl -FileName $_.FileName -Path $env:TEMP -AsFile -force

        #Add Attachment to Target List Item
        $FileStream = New-Object IO.FileStream(($env:TEMP+"\"+$_.FileName),[System.IO.FileMode]::Open)  
        $AttachmentInfo = New-Object -TypeName Microsoft.SharePoint.Client.AttachmentCreationInformation
        $AttachmentInfo.FileName = $_.FileName
        $AttachmentInfo.ContentStream = $FileStream
        $AttachFile = $TargetItem.AttachmentFiles.add($AttachmentInfo)
        $Context.ExecuteQuery()    
    
        #Delete the Temporary File
        Remove-Item -Path $env:TEMP\$($_.FileName) -Force
        }
    }
    Catch {
        write-host -f Red "Error Copying Attachments:" $_.Exception.Message
    }
}

#Function to list items from one list to another
Function Copy-SPOListItems()
{
    param
    (
        [Parameter(Mandatory=$true)] [string] $SourceListName,
        [Parameter(Mandatory=$true)] [string] $TargetListName
    )
    Try {
        #Get All Items from the Source List in batches 
        Write-Progress -Activity "Reading Source..." -Status "Getting Items from Source List. Please wait..."
        $SourceListItems = Get-PnPListItem -List $SourceListName -PageSize 500
        $SourceListItemsCount= $SourceListItems.count
        Write-host "Total Number of Items Found:"$SourceListItemsCount        

        #Get fields to Update from the Source List - Skip Read only, hidden fields, content type and attachments
        $SourceListFields = Get-PnPField -List $SourceListName | Where { (-Not ($_.ReadOnlyField)) -and (-Not ($_.Hidden)) -and ($_.InternalName -ne  "ContentType") -and ($_.InternalName -ne  "Attachments") }
    
        #Loop through each item in the source and Get column values, add them to target
        [int]$Counter = 1
        ForEach($SourceItem in $SourceListItems)
        {  
            $ItemValue = @{}
            #Map each field from source list to target list
            Foreach($SourceField in $SourceListFields)
            {
                #Check if the Field value is not Null
                If($SourceItem[$SourceField.InternalName] -ne $Null)
                {
                    #Handle Special Fields
                    $FieldType  = $SourceField.TypeAsString

                    If($FieldType -eq "User" -or $FieldType -eq "UserMulti" -or $FieldType -eq "Lookup" -or $FieldType -eq "LookupMulti") #People Picker or Lookup Field
                    {
                        $LookupIDs = $SourceItem[$SourceField.InternalName] | ForEach-Object { $_.LookupID.ToString()}
                        $ItemValue.add($SourceField.InternalName,$LookupIDs)
                    }
                    ElseIf($FieldType -eq "URL") #Hyperlink
                    {
                        $URL = $SourceItem[$SourceField.InternalName].URL
                        $Description  = $SourceItem[$SourceField.InternalName].Description
                        $ItemValue.add($SourceField.InternalName,"$URL, $Description")
                    }
                    ElseIf($FieldType -eq "TaxonomyFieldType" -or $FieldType -eq "TaxonomyFieldTypeMulti") #MMS
                    {
                        $TermGUIDs = $SourceItem[$SourceField.InternalName] | ForEach-Object { $_.TermGuid.ToString()}                    
                        $ItemValue.add($SourceField.InternalName,$TermGUIDs)
                    }
                    Else
                    {
                        #Get Source Field Value and add to Hashtable
                        $ItemValue.add($SourceField.InternalName,$SourceItem[$SourceField.InternalName])
                    }
                }
            }
            Write-Progress -Activity "Copying List Items:" -Status "Copying Item ID '$($SourceItem.Id)' from Source List ($($Counter) of $($SourceListItemsCount))" -PercentComplete (($Counter / $SourceListItemsCount) * 100)
        
            #Copy column value from source to target
            $NewItem = Add-PnPListItem -List $TargetListName -Values $ItemValue

            #Copy Attachments
            Copy-SPOAttachments -SourceItem $SourceItem -TargetItem $NewItem

            Write-Host "Copied Item ID from Source to Target List:$($SourceItem.Id) ($($Counter) of $($SourceListItemsCount))"
            $Counter++
        }
    }
    Catch {
        Write-host -f Red "Error:" $_.Exception.Message 
    }
}

#Connect to PnP Online
Connect-PnPOnline -Url "https://crescent.sharepoint.com/sites/marketing/" -Credentials (Get-Credential)
$Context = Get-PnPContext

#Call the Function to Copy List Items between Lists
Copy-SPOListItems -SourceListName "Projects" -TargetListName "ProjectsArchive"

Si desea copiar elementos de la lista entre sitios, utilice: ¿Cómo copiar elementos de la lista entre colecciones de sitios en SharePoint Online usando PowerShell?

Artículos relacionados