Error when using script to download all documents from a SharePoint online document library

Copper Contributor

Hi everyone,

 

I'm using the following script to try to download all files from a document library:

 
Function Download-AllFilesFromLibrary()
{
    param
    (
        [Parameter(Mandatory=$true)] [string] $SiteURL,
        [Parameter(Mandatory=$true)] [Microsoft.SharePoint.Client.Folder] $SourceFolder,
        [Parameter(Mandatory=$true)] [string] $TargetFolder
    )
    Try {
         
        #Create Local Folder, if it doesn't exist
        $FolderName = ($SourceFolder.ServerRelativeURL) -replace "/","\"
        $LocalFolder = $TargetFolder + $FolderName
        If (!(Test-Path -Path $LocalFolder)) {
                New-Item -ItemType Directory -Path $LocalFolder | Out-Null
        }
         
        #Get all Files from the folder
        $FilesColl = $SourceFolder.Files
        $Ctx.Load($FilesColl)
        $Ctx.ExecuteQuery()
 
        #Iterate through each file and download
        Foreach($File in $FilesColl)
        {
            $TargetFile = $LocalFolder+"\"+$File.Name
            #Download the file
            $FileInfo = [Microsoft.SharePoint.Client.File]::OpenBinaryDirect($Ctx,$File.ServerRelativeURL)
            $WriteStream = [System.IO.File]::Open($TargetFile,[System.IO.FileMode]::Create)
            $FileInfo.Stream.CopyTo($WriteStream)
            $WriteStream.Close()
            write-host -f Green "Downloaded File:"$TargetFile
        }
         
        #Process Sub Folders
        $SubFolders = $SourceFolder.Folders
        $Ctx.Load($SubFolders)
        $Ctx.ExecuteQuery()
        Foreach($Folder in $SubFolders)
        {
            If($Folder.Name -ne "Forms")
            {
                #Call the function recursively
                Download-AllFilesFromLibrary -SiteURL $SiteURL -SourceFolder $Folder -TargetFolder $TargetFolder
            }
        }
  }
    Catch {
        write-host -f Red "Error Downloading Files from Library!" $_.Exception.Message
    }
}
 
#Set parameter values
$SiteURL='https://xxxxxxx.sharepoint.com/sites/xxxxxxx/'
$LibraryName='Documents'
$TargetFolder='C:\temp\test'
 
#Setup Credentials to connect
#$Cred= Get-Credential
#$Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)
Connect-PnPOnline -Url $siteURL -Interactive


#Setup the context
$Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$Ctx.Credentials = $Credentials
Connect-PnPOnline -Url $siteURL -Interactive
      
#Get the Library
$List = $Ctx.Web.Lists.GetByTitle($LibraryName)
$Ctx.Load($List)
$Ctx.Load($List.RootFolder)
Connect-PnPOnline -Url $siteURL -Interactive
$Ctx.ExecuteQuery()

 
#Call the function: sharepoint online download multiple files powershell
Download-AllFilesFromLibrary -SiteURL $SiteURL -SourceFolder $List.RootFolder -TargetFolder $TargetFolder

 

Unfortunately I always get this error (on $Ctx.ExecuteQuery())

Exception calling "ExecuteQuery" with "0" argument(s): "The remote server returned an error" (403) Not permitted."
At line:1 char:1
+ $Ctx.ExecuteQuery()
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : WebException

 

But I have all the rights (site admin, SharePoint admin), etc... Anyone got any idea how to solve this?

 

Thanks!

 

2 Replies
I'm unsure if this is still an issue for you, but did you update your PnP.PowerShell module?

@Aron1560 

 

I don't work with SharePoint, but I can see two things of importance:

 

  1. The PnP module effectively isn't being used because the .NET classes are being used directly (i.e. the various Connect-PnPOnline statements achieve nothing as no further PnP commandlets are being called);
  2. $Ctx.Credentials on line 67 is being set to $null, since $Credentials is a non-existent variable (given it's commented out earlier on line 61).

 

I'd expect point 2 relates directly to the HTTP 403, while point 1 is just an observation.

 

Cheers,

Lain