SharePoint Online: Upload a Folder using PowerShell

Requirement: Upload a Folder to SharePoint Online using PowerShell.

How to upload a Folder to SharePoint Online Document Library?

You can upload a folder along with its contents to SharePoint. Here is how to upload a folder with its sub-folders and files to a SharePoint Online document library:

  • Navigate to your SharePoint Online library >> Click on “Upload” from the toolbar, choose the “Folder” option. You’ll get a Browse dialog box to select a folder from your computer.
    How to Upload a Folder to SharePoint Online?
  • Select a folder to copy that entire folder to SharePoint Online library.

This will upload the folder and its contents from the local computer to SharePoint Online. Please note, this option doesn’t work in IE 11. (But works in Edge, Google Chrome, and Firefox browsers!). You can also upload a folder with files and sub-folders to SharePoint Online modern libraries, just by Drag and Drop!

PowerShell to upload a Folder to SharePoint Online (Including Folder, Sub-Folders, and Files):

We can also use PowerShell to copy a folder to SharePoint Online from the local disk. Let’s upload a folder to SharePoint Online using PowerShell, Here is my source:

upload folder to sharepoint online powershell
Prerequisites: Make sure you have installed SharePoint Online Client
Components SDK in your machine to use client-side assemblies. You can download it from https://www.microsoft.com/en-us/download/details.aspx?id=42038

Here is how to Upload a Folder to SharePoint Online Document Library using PowerShell:

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

#Function to Check if Folder Exists. If not, Create the Folder
Function Ensure-SPOFolder()
{
    param
    (
        [Parameter(Mandatory=$true)] [string] $FolderRelativeURL
    )

    #Check Folder Exists
    Try { 
        $Folder = $Web.GetFolderByServerRelativeUrl($FolderRelativeURL)
        $Ctx.Load($Folder)
        $Ctx.ExecuteQuery() 
 
        #Write-host -f Green "Folder Already Exists!"
    }
    Catch {
        #Create New Sub-Folder
        $Folder=$Web.Folders.Add($FolderRelativeURL)
        $Ctx.ExecuteQuery()
        Write-host -f Green "Created Folder at "$FolderRelativeURL
    }
}

#Function to Upload a File to a SharePoint Online
Function Upload-SPOFile()    
{
    param
    (
        [Parameter(Mandatory=$true)] [string] $SourceFilePath,
        [Parameter(Mandatory=$true)] [string] $TargetFileURL
    )
    
    #Get the file from disk
    $FileStream = ([System.IO.FileInfo] (Get-Item $SourceFilePath)).OpenRead()
    #Get File Name from source file path
    $SourceFileName = Split-path $SourceFilePath -leaf
   
    #Upload the File to SharePoint Library
    $FileCreationInfo = New-Object Microsoft.SharePoint.Client.FileCreationInformation
    $FileCreationInfo.Overwrite = $true
    $FileCreationInfo.ContentStream = $FileStream
    $FileCreationInfo.URL = $TargetFileURL
    $FileUploaded = $TargetFolder.Files.Add($FileCreationInfo)
  
    $Ctx.ExecuteQuery()  
    #Close file stream
    $FileStream.Close()
    Write-host "File '$TargetFileURL' Uploaded Successfully!" -ForegroundColor Green
}
 
#Main Function to upload a Local Folder to SharePoint Online Document Library Folder
Function Upload-SPOFolder()
{ 
    param
    (
        [Parameter(Mandatory=$true)] [string] $SourceFolderPath,
        [Parameter(Mandatory=$true)] [Microsoft.SharePoint.Client.Folder] $TargetFolder        
    )

    #Get All Files and Sub-Folders from Source
    Get-ChildItem $SourceFolderPath -Recurse | ForEach-Object {
        If ($_.PSIsContainer -eq $True) 
        {
            $FolderRelativeURL = $TargetFolder.ServerRelativeURL+$_.FullName.Replace($SourceFolderPath,[string]::Empty).Replace("\","/")
            If($FolderRelativeURL) 
            {
                Write-host -f Yellow "Ensuring Folder '$FolderRelativeURL' Exists..."
                Ensure-SPOFolder -FolderRelativeURL $FolderRelativeURL
            }  
        }
        Else
        {
            $FolderRelativeUrl = $TargetFolder.ServerRelativeURL + $_.DirectoryName.Replace($SourceFolderPath,[string]::Empty).Replace("\","/")
            $FileRelativeURL = $FolderRelativeUrl+"/"+$_.Name
            Write-host -f Yellow "Uploading File '$_' to URL "$FileRelativeURL
            Upload-SPOFile -SourceFilePath $_.FullName -TargetFileURL $FileRelativeURL
        }
    }
}

#Set parameter values
$SiteURL="https://crescent.sharepoint.com/sites/marketing"
$LibraryName="Documents"
$SourceFolderPath="C:\Users\salaudeen\Desktop\Marketing\Documents"
 
#Setup Credentials to connect
$Cred= Get-Credential
$Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)
 
#Setup the context
$Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$Ctx.Credentials = $Credentials
      
#Get the Target Folder to Upload
$Web = $Ctx.Web
$Ctx.Load($Web)
$List = $Web.Lists.GetByTitle($LibraryName)
$Ctx.Load($List)
$Ctx.Load($List.RootFolder)
$Ctx.ExecuteQuery() 
 
#Call the function to Upload All files & folders from local folder to SharePoint Online
Upload-SPOFolder -SourceFolderPath $SourceFolderPath -TargetFolder $List.RootFolder

This PowerShell uploads the given folder, sub-folder, and files to SharePoint Online.

powershell to upload folder structure to sharepoint online

Here is the PnP PowerShell version of this script which uploads a folder with its subfolders and files: Upload Multiple files to SharePoint Online using PnP PowerShell

Salaudeen Rajack

Information Technology Professional with Two decades of SharePoint Experience.

6 thoughts on “SharePoint Online: Upload a Folder using PowerShell

  • July 13, 2021 at 2:00 AM

    What would we need to add to the script in order for it to delete the source file after successful upload to Sharepoint?
    Also, this only seems to work to the root of a document library. What do we need to do to point it at a sub folder? (for example – right now this works perfectly –> https://mysharepointsite.sharepoint.com/sites/MyTeamSite/TestDocLibrary….. But how do I upload to this target –> https://mysharepointsite.sharepoint.com/sites/MyTeamSite/TestDocLibrary/SubFolder1/SubFolder2???)

    Reply
  • April 8, 2021 at 2:50 AM

    How would i get the code to Skip a Folder? i have tried to add a | Where {$_.name -NotLike “*Archives*”}

    to a few lines but it produces an error. (it still uploads) but searches every sub folder taking a LONG time to upload the files.

    Reply
  • May 22, 2020 at 12:57 AM

    Thank you so much. Saved me a ton of time and your script worked perfectly.

    Reply
  • August 2, 2019 at 12:28 PM

    You saved me!

    But, there is an interesting task:
    How to Upload a Folders to SharePoint Online SubFolder using PowerShell (Url = “https://test.sharepoint.com/Sites/Libary/Folder/SubFolder”)?

    Thank you for your time and effort in advance!

    Reply
    • August 6, 2019 at 10:09 AM

      Sure, Use this script to get the sub folder:

      $FolderServerRelativeUrl= “/Sites/Marketing/Shared Documents/2017”

      #Get the Folder by Server Relative URL
      $Folder = $Web.GetFolderByServerRelativeUrl($FolderServerRelativeUrl)
      $Ctx.Load($Folder)
      $Ctx.ExecuteQuery()

      Reply
    • August 7, 2019 at 9:44 AM

      Thank you!

      But, I still get an error. If you can and have time, check please:

      #Set parameter values
      $SiteURL=”https://test.sharepoint.com/teams/Ukraine/”
      #$LibraryName=”TempBackup”
      $FolderServerRelativeUrl=”/Ukraine/TempBackup/ADVANCE/APPROVED/”
      $SourceFolderPath=”D:FilespublicADVANCEFORMULARS”
      $Username = “logon_name”
      $Password = Get-Content “password_path.txt” | ConvertTo-SecureString

      #Load SharePoint CSOM Assemblies
      Add-Type -Path “C:Program FilesCommon FilesMicrosoft SharedWeb Server Extensions15ISAPIMicrosoft.SharePoint.Client.dll”
      Add-Type -Path “C:Program FilesCommon FilesMicrosoft SharedWeb Server Extensions15ISAPIMicrosoft.SharePoint.Client.Runtime.dll”

      #Setup Credentials to connect
      $Creds = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Username, $Password)
      $Credentials = $Creds

      #Setup the context
      $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
      $Ctx.Credentials = $Credentials

      #Function to Check if Folder Exists. If not, Create the Folder
      Function Ensure-SPOFolder()
      {
      param
      (
      [Parameter(Mandatory=$true)] [string] $FolderServerRelativeURL
      )

      #Check Folder Exists
      Try {
      $Folder = $SPWeb.GetFolderByServerRelativeUrl($FolderServerRelativeURL)
      $Ctx.Load($Folder)
      $Ctx.ExecuteQuery()

      #Write-host -f Green “Folder Already Exists!”
      }
      Catch {
      #Create New Sub-Folder
      $Folder=$SPWeb.Folders.Add($FolderServerRelativeURL)
      $Ctx.ExecuteQuery()
      Write-host -f Green “Created Folder at “$FolderServerRelativeURL
      }
      }

      #Function to Upload a File to a SharePoint Online
      Function Upload-SPOFile()
      {
      param
      (
      [Parameter(Mandatory=$true)] [string] $SourceFilePath,
      [Parameter(Mandatory=$true)] [string] $TargetFileURL
      )

      #Get the file from disk
      $FileStream = ([System.IO.FileInfo] (Get-Item $SourceFilePath)).OpenRead()
      #Get File Name from source file path
      $SourceFileName = Split-path $SourceFilePath -leaf

      #Upload the File to SharePoint Library
      $FileCreationInfo = New-Object Microsoft.SharePoint.Client.FileCreationInformation
      $FileCreationInfo.Overwrite = $true
      $FileCreationInfo.ContentStream = $FileStream
      $FileCreationInfo.URL = $TargetFileURL
      $FileUploaded = $TargetFolder.Files.Add($FileCreationInfo)

      $Ctx.ExecuteQuery()
      #Close file stream
      $FileStream.Close()
      Write-host “File ‘$TargetFileURL’ Uploaded Successfully!” -ForegroundColor Green
      }

      #Main Function to upload a Local Folder to SharePoint Online Document Library Folder
      Function Upload-SPOFolder()
      {
      param
      (
      [Parameter(Mandatory=$true)] [string] $SourceFolderPath,
      [Parameter(Mandatory=$true)] [Microsoft.SharePoint.Client.Folder] $TargetFolder
      )

      #Get All Files and Sub-Folders from Source
      Get-ChildItem $SourceFolderPath -Recurse | ForEach-Object {
      If ($_.PSIsContainer -eq $True)
      {
      $FolderServerRelativeURL = $TargetFolder.ServerRelativeURL+$_.FullName.Replace($SourceFolderPath,””).Replace(“”,”/”)
      If($FolderServerRelativeURL)
      {
      Write-host -f Yellow “Ensuring Folder ‘$FolderServerRelativeURL’ Exists…”
      Ensure-SPOFolder -FolderServerRelativeURL $FolderServerRelativeURL
      }
      }
      Else
      {
      $FolderServerRelativeUrl = $TargetFolder.ServerRelativeURL + $_.DirectoryName.Replace($SourceFolderPath,””).Replace(“”,”/”)
      $FileRelativeURL = $FolderServerRelativeUrl+”/”+$_.Name
      Write-host -f Yellow “Uploading File ‘$_’ to URL “$FileRelativeURL
      Upload-SPOFile -SourceFilePath $_.FullName -TargetFileURL $FileRelativeURL
      }
      }
      }

      #Get the Target Folder to Upload
      $Web = $Ctx.Web
      $Ctx.Load($Web)
      $List = $Web.Lists.GetByTitle($FolderServerRelativeUrl)
      $Ctx.Load($List)
      $Ctx.Load($List.RootFolder)
      $Ctx.ExecuteQuery()

      #Call the function to Upload All files & folders from local folder to SharePoint Online
      Upload-SPOFolder -SourceFolderPath $SourceFolderPath -TargetFolder $List.RootFolder

      Reply

Leave a Reply