1

I want all users on my SharePoint Online 2013 (plan 2) to be able to 'drop' files in a SharePoint folder, after which an unattended process downloads these files onto a local folder on a Windows Server 2012 and then deletes them from SPO.

The only way I can think of of doing this is through a scheduled PowerShell script. So I am looking for a script that can move all files in a specific folder on SharePoint Online 2013 to a local folder. After downloading I want these files removed from SharePoint. This whole process should be able to run unattended.

Is this the right way to go? Who can point me towards examples / documentation?

2

This can be converted to PowerShell, or be executed as C#, however you wish:

using ( var ctx = new ClientContext( "siteUrl" ) )
{
    ctx.Credentials = new SharePointOnlineCredentials( userName, secureStringPassword );
    var query = new CamlQuery
                {
                    ViewXml = "<View Scope='RecursiveAll'>" +
                              "<Query>" +
                              "<Where>" +
                              "<Eq>" +
                              "<FieldRef Name='FSObjType'/>" +
                              "<Value Type='Int'>0</Value>" +
                              "</Eq>" +
                              "</Where>" +
                              "</Query>" +
                              "</View>"
                };
    var web = ctx.Web;
    var list = web.Lists.GetByTitle( library);
    var items = list.GetItems( query );
    ctx.Load( items, collection => collection.Include( i => i.File.ServerRelativeUrl, i => i.File.Name ) );
    ctx.ExecuteQuery();
    if ( items != null )
        foreach(var item in items)
        {
            using ( var fi = File.OpenBinaryDirect( ctx, item.File.ServerRelativeUrl ) )
            {
                FileStream fileStream;
                using ( fileStream = new FileStream( @"fileDestination", FileMode.Create ) )
                {
                    if ( fi != null ) fi.Stream.CopyTo( fileStream );
                }
            }
        }
}

Be aware of timeouts. If the library contains several files, you may get a timeout error. You can try setting the ClientContext.RequestTimeout, but that never seems to work for me.

0

It sounds like a right way to go.

In order to download files from SharePoint you could utilize File.OpenBinaryDirect method

Example

The below example demonstrates how to download files from a specific folder

Add-Type –Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll" 
Add-Type –Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll" 



Function Download-File(){
param(
   $listItem = $(throw “Please provide a List Item”),
   $downloadPath = $(throw “Please specify a Path”)
)

  $context = $listItem.Context 
  $fileUrl = $listItem["FileRef"]
  $fi = new-object System.IO.FileInfo($listItem["FileRef"])
  $fileInfo = [Microsoft.SharePoint.Client.File]::OpenBinaryDirect($context, $fileUrl);
  try{
     $fileName = [System.IO.Path]::Combine($downloadPath,$fi.Name)
     $fileStream = [System.IO.File]::Create($fileName)           
     $fileInfo.Stream.CopyTo($fileStream)
  }
  finally {
     $fileStream.Dispose()
  }
}



$Url = "https://tenant.sharepoint.com/"
$UserName = "username@tenant.onmicrosoft.com"
$Password = "password"
$listTitle = "Documents"
$folder = "/Shared Documents/Archive"



if([string]::IsNullOrEmpty($Password)) {
   $SecurePassword = Read-Host -Prompt "Enter the password" -AsSecureString 
}
else {
   $SecurePassword = $Password | ConvertTo-SecureString -AsPlainText -Force
}


$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($Url)
$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName,$SecurePassword)
$ctx.credentials = $credentials

#Retive items from a specific folder
$list = $ctx.Web.Lists.GetByTitle($listTitle)
$query = [Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery()
$query.FolderServerRelativeUrl=$folder;
$items = $list.GetItems($query)
$ctx.Load($items)
$ctx.ExecuteQuery()


#Download file(s)
foreach ($item in $items){

  if($item.FileSystemObjectType -ne [Microsoft.SharePoint.Client.FileSystemObjectType ]::File) {
     continue
  } 
  Download-File $item "C:\Temp\Archive"


  #Delete Item
  $item.DeleteObject()
  $ctx.ExecuteQuery()
}  

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.