SharePoint Online: Download Attachments from List using PowerShell

Requirement: Download attachments from SharePoint Online List.

How to download attachments from SharePoint List Items?
Well, to download attachments of a particular list item, you can open the item in either in view or edit mode, right-click on each attachment and choose save from browser context menu. In case, you want to download all attachments from a list item or all list items, use the "Map Network Drive" feature. Here is how:
  • Go to Windows Explorer (Windows Key + E), Right-click on "This PC" from left tree view and choose "Map Network Drive"
  • Select the drive such as "Z:" and enter the URL of your SharePoint list. E.g. http://intranet.crescent.com/Lists/Credit/
  • This opens the Windows explorer view with attachments folder. Attachments are organized with sub-folders under the attachment folder. Your list item id becomes the name of the sub-folder! from here, you can download all attachments by simply copy-pasting to your local machine.
    Download Attachments from List using PowerShel

PowerShell to download attachments from a List Item:
Let's download SharePoint list item attachment programmatically from a particular list item.
#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 Download-ListItemAttachments()
{
    param
    (
        [Parameter(Mandatory=$true)] [string] $SiteURL,
        [Parameter(Mandatory=$true)] [string] $ListName,
        [Parameter(Mandatory=$true)] [string] $ListItemID,
        [Parameter(Mandatory=$true)] [string] $DownloadPath
    )    
   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 List Item
        $List = $Ctx.Web.Lists.GetByTitle($ListName)
        $ListItem= $List.GetItemByID($ListItemID)
    
        #Get All attachments from the List Item
        $AttachmentsColl = $ListItem.AttachmentFiles
        $Ctx.Load($AttachmentsColl)
        $Ctx.ExecuteQuery()
    
        #Get each attachment
        ForEach($Attachment in $AttachmentsColl)
        {
            #Download attachment
            $FileContent = [Microsoft.SharePoint.Client.File]::OpenBinaryDirect($Ctx, $Attachment.ServerRelativeUrl)
            $FileStream = [System.IO.File]::Create($DownloadPath+$Attachment.FileName)
            $FileContent.Stream.CopyTo($FileStream)
            $FileStream.Close()
       }

        write-host  -f Green "Total List Attachments Downloaded : $($AttachmentsColl.count)"
    }
    Catch {
        write-host -f Red "Error Downloading List Item Attachments!" $_.Exception.Message
    } 
}

#Set Parameters
$SiteURL= "https://crescent.sharepoint.com/"
$ListName="Projects"
$ListItemID="1"
$DownloadPath="C:\Temp\"

#Call the function to copy list items
Download-ListItemAttachments -SiteURL $SiteURL -ListName $ListName -ListItemID $ListItemID -DownloadPath $DownloadPath

Download Attachments from All Items in the List using PowerShell:
Here is the PowerShell to download SharePoint Online list attachments from all 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 Download-ListAttachments()
{
    param
    (
        [Parameter(Mandatory=$true)] [string] $SiteURL,
        [Parameter(Mandatory=$true)] [string] $ListName,
        [Parameter(Mandatory=$true)] [string] $DownloadDirectory
    )    
   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 All Items from the List
        $List = $Ctx.Web.Lists.GetByTitle($ListName)
        $ListItems = $List.GetItems([Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery())
        $Ctx.Load($ListItems)
        $Ctx.ExecuteQuery()
        
        #Create download directory if it doesn't exist
        If (!(Test-Path -path $DownloadDirectory))        
        {            
            New-Item $DownloadDirectory -type directory          
        }
        
        #Iterate through each list item
        Foreach($Item in $ListItems)
        {
            #Get All attachments from the List Item
            $AttachmentsColl = $Item.AttachmentFiles
            $Ctx.Load($AttachmentsColl)
            $Ctx.ExecuteQuery()

            #Get attachment for each list item
            ForEach($Attachment in $AttachmentsColl)
            {
                #Download attachment
                $FileContent = [Microsoft.SharePoint.Client.File]::OpenBinaryDirect($Ctx, $Attachment.ServerRelativeUrl)
                $FileName= $DownloadDirectory+$Item.id.ToString()+"_"+$Attachment.FileName
                $FileStream = [System.IO.File]::Create($FileName)
                $FileContent.Stream.CopyTo($FileStream)
                $FileStream.Close()
           }
        }

        write-host  -f Green "List Attachments Downloaded Successfully!"
    }
    Catch {
        write-host -f Red "Error Downloading List Attachments!" $_.Exception.Message
    } 
}

#Set Parameters
$SiteURL= "https://crescent.sharepoint.com/"
$ListName="Projects"
$DownloadDirectory="C:\Temp\"

#Call the function to copy list items
Download-ListAttachments -SiteURL $SiteURL -ListName $ListName -DownloadDirectory $DownloadDirectory

SharePoint Online: Download Attachments from List Item using PnP PowerShell
This PowerShell downloads all attachments from a given list item.
#Set Parameters
$SiteURL = "https://crescent.sharepoint.com/sites/Projects"
$ListName = "Docs"
$ItemID = "1"
$DownloadPath = "C:\Temp\"

#Connect to SharePoint Online site
Connect-PnPOnline -Url $SiteURL -UseWebLogin

#Get the List Item
$Listitem = Get-PnPListItem -List $ListName -Id $ItemID

#Get Attachments from List Item
$Attachments = Get-PnPProperty -ClientObject $Listitem -Property "AttachmentFiles"

#Download All Attachments from List item
Write-host "Total Number of Attachments Found:"$Attachments.Count

$Attachments | ForEach-Object { 
    Get-PnPFile -Url $_.ServerRelativeUrl -FileName $_.FileName -Path $DownloadPath -AsFile 
}

Download Attachment from SharePoint Online List using PnP PowerShell
Let's download all attachments from a list. This script creates a folder for each list item and downloads all attachments from it. 
#Set Parameters
$SiteURL = "https://crescent.sharepoint.com/sites/Projects"
$ListName = "Project Docs"
$DownloadPath = "C:\Temp\"

#Connect to SharePoint Online site
Connect-PnPOnline -Url $SiteURL -UseWebLogin

#Get all List Items
$Listitems = Get-PnPListItem -List $ListName -PageSize 500

#Iterate through List Items
ForEach($Item in $Listitems)
{
    #Get Attachments from List Item
    $Attachments = Get-PnPProperty -ClientObject $Item -Property "AttachmentFiles"

    #Download All Attachments from List item
    Write-host "Downloading Attachments from List item '$($Item.ID)', Attachments Found: $($Attachments.Count)"

    #Create directory for each list item
    $DownloadLocation = $DownloadPath+$Item.ID
    If (!(Test-Path -path $DownloadLocation)) { New-Item $DownloadLocation -type Directory | Out-Null }

    $Attachments | ForEach-Object { 
        Get-PnPFile -Url $_.ServerRelativeUrl -FileName $_.FileName -Path $DownloadLocation -AsFile -Force
    }
}
This extracts all attachments from all list items to local disk.

9 comments:

  1. Can i change id to another filed here ??

    ReplyDelete
    Replies
    1. Yes, If the field is unique! Otherwise, when a same attachment file name found in more than one list item, that may gets overwritten.

      Delete
  2. Thank you so much!!!! mapping the drive was just what I was looking for

    ReplyDelete
  3. When dealing with list items with multiple attachments, how can I download these attachments organized by the list item they were under?

    ReplyDelete
    Replies
    1. This script creates a folder for each list item based on list item ID and then downloads all attachments inside the folder!

      Delete
  4. any idea on how to upload multiple attachments to different list items.
    thanks

    ReplyDelete
  5. Any way to upload multiple attachments using list id. I mean the other way round?

    ReplyDelete
    Replies
    1. Thanks fo the reply. But this is just to add for 1 list item. I need something where i got like 1500 list items and want to add attachments to those items with mapped column name as folder name for attachment. Is that possible ?

      Delete

Please Login and comment to get your questions answered!

Powered by Blogger.