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?
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):
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,"").Replace("\","/")
            If($FolderRelativeURL) 
            {
                Write-host -f Yellow "Ensuring Folder '$FolderRelativeURL' Exists..."
                Ensure-SPOFolder -FolderRelativeURL $FolderRelativeURL
            }  
        }
        Else
        {
            $FolderRelativeUrl = $TargetFolder.ServerRelativeURL + $_.DirectoryName.Replace($SourceFolderPath,"").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

4 comments:

  1. 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!

    ReplyDelete
    Replies
    1. 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()

      Delete
    2. 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:\Files\public\ADVANCE\FORMULARS"
      $Username = "logon_name"
      $Password = Get-Content "password_path.txt" | ConvertTo-SecureString

      #Load SharePoint CSOM Assemblies
      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"

      #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

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

    ReplyDelete

Please Login and comment to get your questions answered!

Powered by Blogger.