Thursday, August 2, 2012

Powershell Script to download attachments on a SharePoint List into a file share

Problem Description: Download all attachments on a SharePoint List to a File Share. Each set of attachments for a List Item need to be in its own folder, with ItemId as the name of the folder.

Solution: Powershell script shown below was run. The script took about 5 minutes to run on a list with 3000 items, each containing between 1 and 5 attachments. Average size of an attachment is between 1 and 5 MB.



   1:  $webUrl = "Url"    
   2:  $library = "ListName"   
   3:  #Local Folder to dump files
   4:  $tempLocation = "FolderPath"     
   5:  $s = new-object Microsoft.SharePoint.SPSite($webUrl)    
   6:  $w = $s.OpenWeb()         
   7:  $l = $w.Lists[$library]    
   8:  foreach ($listItem in $l.Items)
   9:  {
  10:      Write-Host "    Content: " $listItem.ID 
  11:       $destinationfolder = $tempLocation + "\" + $listItem.ID          
  12:        if (!(Test-Path -path $destinationfolder))        
  13:         {            
  14:          $dest = New-Item $destinationfolder -type directory          
  15:         }
  16:      foreach ($attachment in $listItem.Attachments)    
  17:          {        
  18:              $file = $w.GetFile($listItem.Attachments.UrlPrefix + $attachment)        
  19:              $bytes = $file.OpenBinary()                
  20:              $path = $destinationfolder + "
\" + $attachment
  21:              Write "
Saving $path"
  22:              $fs = new-object System.IO.FileStream($path, "
OpenOrCreate")
  23:              $fs.Write($bytes, 0 , $bytes.Length)    
  24:              $fs.Close()    
  25:          }
  26:  }

Reference: Thanks to this blogpost. I tweaked the script mentioned on this blog post for the above purpose.



9 comments:

N.Forbes said...

Thanks so much. This enabled us to automate export/import from a SharePoint List to a HelpDesk application.

I was able to add a filter to this as I only wanted attachments for "Open" issues. In my example below, "Closed" is a Yes/No field.

$query = new-object Microsoft.SharePoint.SPQuery;
$query.Query = "0";
$FilteredList = $l.getitems($query);
foreach ($item in $FilteredList) {

N.Forbes said...
This comment has been removed by the author.
N.Forbes said...

$query.Query = "<Where><Eq><FieldRef Name='Closed'/><Value Type='String'>0</Value></Eq></Where>";

Khushi said...

Your post is very very very helpful. Thank you so much Ashish!!
I owe you.

Thanks,
Khushi

Anonymous said...

Hi Ashish,

Please can you let me know what ammendments i'll need to do to your script to get attachments that are associated with a Library folder (in site content) and not in the attachments column in the list.

kind regards

Mark

AvibaD said...

Man.... this post made wonders! Its super easy to edit and made it to work. Thanks a lot for sharing it.!

Unknown said...

Hi

I Encounter this error:

New-Object : Cannot find type [Microsoft.SharePoint.SPSite]: make sure the assembly containing this type is loaded.
At line:6 char:16
+ $s = new-object <<<< Microsoft.SharePoint.SPSite($webUrl)
+ CategoryInfo : InvalidType: (:) [New-Object], PSArgumentException
+ FullyQualifiedErrorId : TypeNotFound,Microsoft.PowerShell.Commands.NewObjectCommand

You cannot call a method on a null-valued expression.
At line:7 char:16
+ $w = $s.OpenWeb <<<< ()
+ CategoryInfo : InvalidOperation: (OpenWeb:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull

Cannot index into a null array.
At line:8 char:15
+ $l = $w.Lists[ <<<< $library]
+ CategoryInfo : InvalidOperation: (CRLog201:String) [], RuntimeException
+ FullyQualifiedErrorId : NullArray

Content:
You cannot call a method on a null-valued expression.
At line:19 char:31
+ $file = $w.GetFile <<<< ($listItem.Attachments.UrlPrefix + $attachment)
+ CategoryInfo : InvalidOperation: (GetFile:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull

You cannot call a method on a null-valued expression.
At line:20 char:38
+ $bytes = $file.OpenBinary <<<< ()
+ CategoryInfo : InvalidOperation: (OpenBinary:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull

Saving C:\Users\JEVS341\Desktop\TestCRFORMS00
Exception calling "Write" with "3" argument(s): "Buffer cannot be null.
Parameter name: array"
At line:24 char:22
+ $fs.Write <<<< ($bytes, 0 , $bytes.Length)
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException

Unknown said...

Hi

Im the one who poasted the error above.

My powershell version is 2.0

My PC is 32-bit.

is this the reason why I get the error?

I've set execution policy to "unrestricted" already.

Thank you.

Best Regards,

Unknown said...

Thanks for the great explanation! I could confirm that approach is still workable in 2019 for Sharepoint Online. In case if you are looking for a no code solution there is 3-rd party tool available for SharePoint Lists Export with Attachments that could be found on www.listman.io.