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 view or edit mode, right-click on each attachment and choose to save from the 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 the 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 the 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.

Salaudeen Rajack

Salaudeen Rajack is a SharePoint Architect with Two decades of SharePoint Experience. He loves sharing his knowledge and experiences with the SharePoint community, through his real-world articles!

9 thoughts on “SharePoint Online: Download Attachments from List using PowerShell

  • May 6, 2020 at 12:01 AM

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

    Reply
  • May 6, 2020 at 12:00 AM

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

    Reply
  • April 7, 2020 at 8:49 PM

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

    Reply
    • April 8, 2020 at 7:04 AM

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

      Reply
  • June 26, 2019 at 10:34 PM

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

    Reply
  • July 18, 2018 at 7:27 AM

    Can i change id to another filed here ??

    Reply
    • April 8, 2020 at 7:06 AM

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

      Reply

Leave a Reply