SharePoint Online: Add Attachment to List Item using PowerShell

Requirement: Add Attachment to SharePoint Online List Item

SharePoint Online: How to Add Attachment to List Item?
To add attachment to list item in SharePoint Online,
  • Navigate to the SharePoint Online list >> Select the List Item you want to add attachments
  • Edit List Item >> Scroll down and Click on "Add Attachments" link in the Edit pane.
    sharepoint online add attachment to list item powershell
  • This opens browse dialog window., Select attachments to add
  • Click on Save to complete adding attachment to list item.
SharePoint Online list item attachment size limit: The file size limit on SharePoint Online list attachments is 250 MB!

PowerShell to Add an Attachment to 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 Add-AttachmentToListItem()
{
    param
    (
        [Parameter(Mandatory=$true)] [string] $SiteURL,
        [Parameter(Mandatory=$true)] [string] $ListName,
        [Parameter(Mandatory=$true)] [string] $ItemID,
        [Parameter(Mandatory=$false)] [string] $AttachmentPath
    )    
    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 & List Item
        $List = $Ctx.Web.Lists.GetByTitle($ListName)
        $Ctx.Load($List)
        $ListItem = $List.GetItemByID($ItemID)
        $Ctx.Load($ListItem)
        $Ctx.ExecuteQuery()

        #Get All existing attachments
        $AttachmentFiles = $ListItem.AttachmentFiles
        $Ctx.Load($AttachmentFiles)
        $Ctx.ExecuteQuery()

        #Check if attachment file name exists already
        $FileName = Split-Path $AttachmentPath -Leaf
        $AttachmentFile = $AttachmentFiles | where { ($_.FileName -eq $FileName) }
        If($AttachmentFile -eq $Null)
        {
            #Get the Attachment file from local disk
            [Byte[]]$Bytes = [System.IO.File]::ReadAllBytes($AttachmentPath)
            $ContentStream = New-Object -TypeName System.IO.MemoryStream -ArgumentList @(,$Bytes)
    
            #Create Attachment object
            $AttachmentCreation = New-Object Microsoft.SharePoint.Client.AttachmentCreationInformation
            $AttachmentCreation.ContentStream = $ContentStream
            $AttachmentCreation.FileName = $FileName
            [Void]$ListItem.AttachmentFiles.Add($AttachmentCreation)
            $Ctx.ExecuteQuery()

            write-host  -f Green "Attachment Added to List Item!" 
        }
        else
        {
            write-host -f Yellow "Attachment File Name Exists already!"
        }
    }
    Catch {
        write-host -f Red "Error Adding Attachment to List!" $_.Exception.Message
    }
}

#Set Parameters
$SiteURL= "https://crescent.sharepoint.com"
$ListName="Projects"
$ItemID="5"
$AttachmentPath="C:\Projects\Proposal.docx"

#Call the function to copy list items
Add-AttachmentToListItem -SiteURL $SiteURL -ListName $ListName -ItemID $ItemID -AttachmentPath $AttachmentPath

PnP PowerShell to Add Attachment to List Item 
Let's add an attachment to the SharePoint Online list item with PnP PowerShell.
#Set Variables
$SiteURL = "https://crescent.sharepoint.com/sites/Marketing"
$ListName = "Projects"
$ItemID ="2"
$FilePath ="C:\Docs\UserInfo.csv"

#Connect to PNP Online
Connect-PnPOnline -Url $SiteURL -Credentials (Get-Credential)

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

#Get the File and Add to List Item Attachment
$FileStream = New-Object IO.FileStream($FilePath,[System.IO.FileMode]::Open) 
$AttachmentInfo = New-Object -TypeName Microsoft.SharePoint.Client.AttachmentCreationInformation 
$AttachmentInfo.FileName =  Split-Path $FilePath -Leaf 
$AttachmentInfo.ContentStream = $FileStream
$AttchedFile = $Item.AttachmentFiles.Add($AttachmentInfo) 
Invoke-PnPQuery
$FileStream.Close()

How about adding multiple attachments to the list item? Lets add all files from a given folder to SharePoint Online.
#Set Variables
$SiteURL = "https://crescent.sharepoint.com/sites/pmo"
$ListName = "Projects"
$ItemID ="2"
$FolderPath = "C:\Temp\Docs"

#Connect to PNP Online
Connect-PnPOnline -Url $SiteURL -UseWebLogin

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

#Function to Add all files as a attachment to list item
Function Add-AttachmentsFromFolder($ListItem, $FolderPath)
{
    #Get All existing attachments from list item
    $AttachmentFiles = Get-PnPProperty -ClientObject $ListItem -Property "AttachmentFiles"

    #Get the File and Add to List Item Attachment
    ForEach ($File in  (Get-ChildItem $FolderPath -File))
    {
        $AttachmentFile = $AttachmentFiles | Where { ($_.FileName -eq $File.Name) }
        If($AttachmentFile -eq $Null)
        {
            $AttachmentInfo = New-Object -TypeName Microsoft.SharePoint.Client.AttachmentCreationInformation 
            $AttachmentInfo.FileName =  $File.Name
            $AttachmentInfo.ContentStream = $File.OpenRead()
            $AttchedFile = $ListItem.AttachmentFiles.Add($AttachmentInfo) 
            Invoke-PnPQuery
            Write-host -f Green "Added Attachment File:"$File.FullName
        }
        Else
        {
            write-host -f Yellow "Attachment '$($File.Name)' Exists already!"
        }
    }
}
#Call the function to add all attachments from folder
Add-AttachmentsFromFolder $ListItem $FolderPath

2 comments:

  1. I am getting error on 49thline.

    Exception calling "ExecuteQuery" with "0" argument(s): "parameters
    Parameter name: Specified value is not supported for the parameters parameter."
    At line:36 char:13
    + $Ctx.ExecuteQuery()
    + ~~~~~~~~~~~~~~~~~~~

    If I remove the line, script has been ran successfully.
    But File has not been uploaded.Please help.

    ReplyDelete
  2. Kudos - this worked almost exactly as I wanted. In my case I wanted my AttachmentPath to reference an online document, which did not work. It only worked when my documents was local. Other than that, it worked perfectly.

    ReplyDelete

Please Login and comment to get your questions answered!

Powered by Blogger.