Requirement: Copy Attachment from one list to another in SharePoint Online.
PowerShell to Copy Attachment to Another List in SharePoint Online:
Had a requirement to copy attachments between SharePoint Online lists. (only attachment - Not list items!). This script gets the attachments from source list, searches the matching list item based on "Mapping Column" value and attaches list attachments to the destination list items.
PowerShell to Copy Attachment to Another List in SharePoint Online:
Had a requirement to copy attachments between SharePoint Online lists. (only attachment - Not list items!). This script gets the attachments from source list, searches the matching list item based on "Mapping Column" value and attaches list attachments to the destination list items.
#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-Attachments()
{
param
(
[Parameter(Mandatory=$true)] [string] $SiteURL,
[Parameter(Mandatory=$true)] [string] $SourceListName,
[Parameter(Mandatory=$true)] [string] $TargetListName,
[Parameter(Mandatory=$false)] [string] $MappingColumn="Title"
)
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 & Target Lists
$SourceList = $Ctx.Web.Lists.GetByTitle($SourceListName)
$TargetList = $Ctx.Web.Lists.GetByTitle($TargetListName)
#Get All Items
$SourceListItems = $SourceList.GetItems([Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery())
$TargetListItems = $TargetList.GetItems([Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery())
$Ctx.Load($SourceListItems)
$Ctx.Load($TargetListItems)
$Ctx.ExecuteQuery()
#Iterate through each list item from source
ForEach($SourceItem in $SourceListItems)
{
#Get All attachments from the List Item
$AttachmentsColl = $SourceItem.AttachmentFiles
$Ctx.Load($AttachmentsColl)
$Ctx.ExecuteQuery()
#Get Matching List item in the target list
$ListItem = $TargetListItems | Where { $_[$MappingColumn] -eq $SourceItem[$MappingColumn]}
if($ListItem -ne $null)
{
#Get attachment for each list item
ForEach($Attachment in $AttachmentsColl)
{
$AttachmentCreation = New-Object Microsoft.SharePoint.Client.AttachmentCreationInformation
#Get the Source attachment
$FileContent = [Microsoft.SharePoint.Client.File]::OpenBinaryDirect($Ctx, $Attachment.ServerRelativeUrl)
$Buffer = New-Object byte[]($FileContent.length)
$BytesRead = $FileContent.stream.Read($Buffer, 0, $Buffer.Length)
$ContentStream = New-Object -TypeName System.IO.MemoryStream ($Buffer)
$AttachmentCreation.ContentStream = $ContentStream
$AttachmentCreation.FileName = $Attachment.FileName
[void]$ListItem.AttachmentFiles.Add($AttachmentCreation)
$Ctx.ExecuteQuery()
}
}
}
write-host -f Green "List Attachments Copied from '$SourceListName' to '$TargetListName' !"
}
Catch {
write-host -f Red "Error Copying List Attachments!" $_.Exception.Message
}
}
#Set Parameters
$SiteURL= "https://crescent.sharepoint.com/"
$SourceListName="Projects"
$TargetListName="Project Temp"
#Call the function to copy list items
Copy-Attachments -siteURL $SiteURL -SourceListName $SourceListName -TargetListName $TargetListName