0

I'm trying to download all documents from a SharePoint library that has more than 200K documents and has obviously exceeded the listview threshold and I haven't been able to find a script that will allow me to download these files. Is there a way to download all of these files using Powershell to a file share?

1 Answer 1

0

You can use the below script :

#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 = "[email protected]"
$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 = "@
    <View Scope='RecursiveAll'>
        <Query>
   <Where>
      <And>
         <Geq>
            <FieldRef Name='Created' />
            <Value IncludeTimeValue='TRUE' Type='DateTime'>$startDateVar</Value>
         </Geq>
         <Leq>
            <FieldRef Name='Created' />
            <Value IncludeTimeValue='TRUE' Type='DateTime'>$endDateVar</Value>
         </Leq>
      </And>
   </Where>
</Query>        
    </View>"


$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)

Source :

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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