SharePoint Online Automation – O365 – Download files from a document library using PowerShell CSOM

No comments

Here in this post – I will show how we can download files or documents from SharePoint online document library using PowerShell CSOM programmatically from the given date by passing “From Date” and “To Date” to the query. Lets say we want to download certain files from SharePoint document library those were created between these two dates – using this script we can download those files.

Here in the below screenshot we can see the file creation date is from September 6 to till date (November 6). Using the code I will download the files those were created since October 28 to till November 6 where I will ensure that the file which was created in September 6 will not be downloaded.

DownloadDocumentsUsingPowerShellCSOM

PowerShell CSOM Script to Download the files:

#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"
cls

$fileName = "File_Downloading_Report"
#'yyyyMMddhhmm   yyyyMMdd
$enddate = (Get-Date).tostring("yyyyMMddhhmmss")
#$filename =  $enddate + '_VMReport.doc'  
$logFileName = $fileName +"_"+ $enddate+"_Log.txt"   
$invocation = (Get-Variable MyInvocation).Value  
$directoryPath = Split-Path $invocation.MyCommand.Path  

$directoryPathForLog=$directoryPath+"\"+"LogFiles"
if(!(Test-Path -path $directoryPathForLog))  
        {  
            New-Item -ItemType directory -Path $directoryPathForLog
            #Write-Host "Please Provide Proper Log Path" -ForegroundColor Red   
        }  


#$logPath = $directoryPath + "\" + $logFileName 

$logPath = $directoryPathForLog + "\" + $logFileName 
  
$isLogFileCreated = $False 

#DLL location

$directoryPathForDLL=$directoryPath+"\"+"Dependency Files"
if(!(Test-Path -path $directoryPathForDLL))  
        {  
            New-Item -ItemType directory -Path $directoryPathForDLL
            #Write-Host "Please Provide Proper Log Path" -ForegroundColor Red   
        } 

#DLL location
$clientDLL=$directoryPathForDLL+"\"+"Microsoft.SharePoint.Client.dll"
$clientDLLRuntime=$directoryPathForDLL+"\"+"Microsoft.SharePoint.Client.dll"

Add-Type -Path $clientDLL
Add-Type -Path $clientDLLRuntime
#File Download location

$directoryPathForFileDownloadLocation=$directoryPath+"\"+"Downloaded Files"
if(!(Test-Path -path $directoryPathForFileDownloadLocation))  
        {  
            New-Item -ItemType directory -Path $directoryPathForFileDownloadLocation
            #Write-Host "Please Provide Proper Log Path" -ForegroundColor Red   
        } 

#File Download location

  

function Write-Log([string]$logMsg)  
{   
    if(!$isLogFileCreated){   
        Write-Host "Creating Log File..."   
        if(!(Test-Path -path $directoryPath))  
        {  
            Write-Host "Please Provide Proper Log Path" -ForegroundColor Red   
        }   
        else   
        {   
            $script:isLogFileCreated = $True   
            Write-Host "Log File ($logFileName) Created..."   
            [string]$logMessage = [System.String]::Format("[$(Get-Date)] - {0}", $logMsg)   
            Add-Content -Path $logPath -Value $logMessage   
        }   
    }   
    else   
    {   
        [string]$logMessage = [System.String]::Format("[$(Get-Date)] - {0}", $logMsg)   
        Add-Content -Path $logPath -Value $logMessage   
    }   
} 



#The below function will download the file from SharePoint Online library.
Function FileDownLoadFromSPOnlineLibrary()
{
    param
    (
        [Parameter(Mandatory=$true)] [string] $SPOSiteURL,
        [Parameter(Mandatory=$true)] [string] $SourceFilePath,
        [Parameter(Mandatory=$true)] [string] $TargetFilePath,
        [Parameter(Mandatory=$true)] [string] $UserName,
        [Parameter(Mandatory=$true)] [string] $Password
    )
 
    Try 
    {      

        $securePassword= $Password | ConvertTo-SecureString -AsPlainText -Force  
        #Setup the Context
        $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SPOSiteURL)
        $ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $securePassword)

        #Downloading the file from SharePoint online document libray.
        $fileInfo = [Microsoft.SharePoint.Client.File]::OpenBinaryDirect($ctx,$SourceFilePath)
        $writeStream = [System.IO.File]::Open($TargetFilePath,[System.IO.FileMode]::Create)
        $fileInfo.Stream.CopyTo($writeStream)
        $writeStream.Close()
 
        Write-host -f Green "File '$SourceFilePath' has been downloaded to '$TargetFilePath' successfully!"
    }
    Catch 
    {
            
            $ErrorMessage = $_.Exception.Message +"in Downloading File!: " +$SourceFilePath
            Write-Host $ErrorMessage -BackgroundColor Red
            Write-Log $ErrorMessage 

    }
}


#Parameters value
$siteURL="https://globalsharepoint.sharepoint.com/sites/TestSite/"
$listName="Documents" #Document library name
$fromDate="2019-10-28"
$toDate="2019-11-09"
$downloadLocation=$directoryPathForFileDownloadLocation;
$userName = "YourSPOAccount@YourTenantDomain.com"
$password = "YourPassWord"
$securePassword= $password | ConvertTo-SecureString -AsPlainText -Force
#$batchSize =1000
#Parameters ends here.

  
#Setup the Context
$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($siteURL)
$ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($userName, $securePassword)
  
#Get the List
$list = $ctx.Web.Lists.GetByTitle($listName)
$ctx.Load($list)
$ctx.ExecuteQuery()
$emptyString = ""
#Define CAML Query to get Files from the list in batches
$Query = New-Object Microsoft.SharePoint.Client.CamlQuery

#Here in the below two line "T13:35:58Z" and "T13:36:34Z" are hard coded static value - because while we construct this camel query thru the camel query builder these values gets appended to the date value, so we need this.
$startDateVar=$fromDate+"T13:35:58Z"  
$endDateVar=$toDate+"T13:36:34Z"
#Here in the below two line "T13:35:58Z" and "T13:36:34Z" are hard coded static value - ends here.
#RecursiveAll
$Query.ViewXml = "@
    
        
   
      
         
            
            $startDateVar
         
         
            
            $endDateVar
         
      
   
        
    "

$count =0
#Get List Items in Batches
Do
{
     

    $ListItems = $List.GetItems($Query)
    $Ctx.Load($ListItems)
    $Ctx.ExecuteQuery()
    $ListItems.Count

    #Update Postion of the ListItemCollectionPosition
    $Query.ListItemCollectionPosition = $ListItems.ListItemCollectionPosition
    $Query.ListItemCollectionPosition
   
    If ($ListItems.Count -eq 0) 
    { 
    Break
    }

    $downloadItemCount=1;
     
    #Extract the each list item from the List Items collection.
    ForEach($Item in $ListItems)
    {                  
          #Example to Item metadata - this can be used if we want to download based on some item metadata condition.
          #$documentStatus=$Item["documentStatusColumnName"]
         
            try
            {
          
                $Ctx.Load($Item.File)
                $Ctx.ExecuteQuery()
                #$eTagVal=$Item.File.ETag                                         
        
                #https://globalsharepoint.sharepoint.com/sites/TestSite/Shared%20Documents/LegalDoc.docx        
                $SourceFile=$Item.File.ServerRelativeUrl;
                #$TargetFile="C:\PowerShell\DownLoadFilesFromSPOnline\Downloaded Files\LegalDoc.docx" 
                $TargetFile=$downloadLocation+"\"+$Item.File.Name; 

                #If we want to download the specific file type we can check the file type using the below code 
                #if($SourceFile.Contains(".zip")){}

                #Calling the function "FileDownLoadFromSPOnlineLibrary"to download file
                FileDownLoadFromSPOnlineLibrary -SPOSiteURL $SiteURL -SourceFilePath $SourceFile -TargetFilePath $TargetFile -UserName $UserName -Password $Password

                $fileDownloadingMessage=$downloadItemCount.ToString()+": "+$Item.File.Name; 
                Write-Host $fileDownloadingMessage -BackgroundColor DarkGreen
                Write-Log $fileDownloadingMessage

        $downloadItemCount++

        }
        catch
        { 
            $ErrorMessage = $_.Exception.Message +"in: " +$Item.File.Name
            Write-Host $ErrorMessage -BackgroundColor Red
            Write-Log $ErrorMessage 

        }

    }
    Write-Host "============================================================="
    Write-Host $count
    Write-Host "============================================================="
    
}While ($Query.ListItemCollectionPosition -ne $null)

File will be downloaded here – just ensuring before executing the script this folder is empty.

DownloadDocumentsUsingPowerShellCSOM2

Execute the above script successfully:

DownloadDocumentsUsingPowerShellCSOM3

Verify the  “Downloaded Files” folder – now we can see four files just have arrived.

DownloadDocumentsUsingPowerShellCSOM4

Note:

In the above location the file which was created before October 28 is not downloaded because we have given filter criteria from October 28 to November 6.

Prerequisites to execute this script:

Need to place the below two DLLs in your script directory “Dependency Files” folder as like below:

DownloadDocumentsUsingPowerShellCSOM5

Change the value of the variable in the variables section like below:

#Variables region 
$siteURL="Site URL"
$listName="Document Library Name" #Document library name
$fromDate="From Date(YYYY-MM-DD)"
$toDate="To Date(YYYY-MM-DD)"
$userName = "YourSPOAccount@YourTenantDomain.com"
$password = "YourPassWord"
#Variables region ends here

 

Summary:

Thus, in this article we have learned the below:

  • Ho to download a file/document from SharePoint online document library using PowerShell CSOM.
  • How to download a file/document from SharePoint folder using PowerShell.