1
votes

I've been attempting to upload files and folders to SharePoint Online using PowerShell. I'm almost there but there is something wrong with the code in the recursive method. It's upload the files into the folder below its supposed to. For example if I had a folder structure and each folder had 3 files:

Folder1\Folder2\Folder3

The files in Folder2 and Folder3 would upload to folder 3.

I know that the folders are getting uploaded first so the path of $UploadSubFolder is updated to the lower folder but I don't know how to fix it! Could you write a bit of code so that the files are uploaded first perhaps?

Can anyone help me with this problem ? Thanks!

    Function ImportFiles()
{
   ForEach($File in Get-ChildItem $CurrentFolder)
   {    
        If($File.PSIsContainer -eq $false)
        {  
              #Upload File to Folder in Sharepoint
              $FileStream = New-Object IO.FileStream($File.FullName,[System.IO.FileMode]::Open)
              $FileCreationInfo = New-Object Microsoft.SharePoint.Client.FileCreationInformation
              $FileCreationInfo.Overwrite = $true
              $FileCreationInfo.ContentStream = $FileStream
              $FileCreationInfo.URL = $File
              $Upload = $UploadSubFolder.Files.Add($FileCreationInfo)
              $Context.Load($Upload)
              $Context.ExecuteQuery() 
        }
        ElseIf($File.PSIsContainer -eq $True)
        { 
              #Upload SubFolder

              $CurrentFolder = $CurrentFolder + "\" + $File.Name
              $NewFolder1 = Split-Path $File -leaf
              $UploadSubFolder = $UploadSubFolder.Folders.Add($NewFolder1) 
              $Context.Load($UploadSubFolder)
              $Context.ExecuteQuery()

              ImportFiles     
        }
        Else
        {
            Write-Host "Upload Complete"
        }
    }
}
#Get name of Root folder
$NewFolder = Split-Path $Folder -Leaf
#upload Root folder to sharepoint 
$UploadFolder = $List.RootFolder.Folders.Add($NewFolder)
$Context.Load($UploadFolder)
$Context.ExecuteQuery()

ForEach($File in (dir $Folder))
{
    if($File.PSIsContainer -eq $false)
    {
          #Upload File to Folder in Sharepoint
          $FileStream = New-Object IO.FileStream($File.FullName,[System.IO.FileMode]::Open)
          $FileCreationInfo = New-Object Microsoft.SharePoint.Client.FileCreationInformation
          $FileCreationInfo.Overwrite = $true
          $FileCreationInfo.ContentStream = $FileStream
          $FileCreationInfo.URL = $File
          $Upload = $UploadFolder.Files.Add($FileCreationInfo)
          $Context.Load($Upload)
          $Context.ExecuteQuery()
    }
    else
    {
            $CurrentFolder = $Folder + "\" + $File.Name
            #upload folder
            $NewFolder = Split-Path $File -leaf
            $UploadSubFolder = $UploadFolder.Folders.Add($NewFolder) 
            $Context.Load($UploadSubFolder)
            $Context.ExecuteQuery()
            ImportFiles 
        }
}
1

1 Answers

0
votes

The following PS script could be used for uploading files into Document Library in SharePoint Online.

How to upload files into Document Library in SharePoint Online

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"



Function Ensure-Folder()
{
Param(
  [Parameter(Mandatory=$True)]
  [Microsoft.SharePoint.Client.Web]$Web,

  [Parameter(Mandatory=$True)]
  [Microsoft.SharePoint.Client.Folder]$ParentFolder, 

  [Parameter(Mandatory=$True)]
  [String]$FolderUrl

)
    $folderUrls = $FolderUrl.Trim().Split("/",[System.StringSplitOptions]::RemoveEmptyEntries)
    $folderUrl = $folderUrls[0]
    $curFolder = $ParentFolder.Folders.Add($folderUrl)
    $Web.Context.Load($curFolder)
    $web.Context.ExecuteQuery()

    if ($folderUrls.Length -gt 1)
    {
        $curFolderUrl = [System.String]::Join("/", $folderUrls, 1, $folderUrls.Length - 1)
        Ensure-Folder -Web $Web -ParentFolder $curFolder -FolderUrl $curFolderUrl
    }
}



Function Upload-File() 
{
Param(
  [Parameter(Mandatory=$True)]
  [Microsoft.SharePoint.Client.Web]$Web,

  [Parameter(Mandatory=$True)]
  [String]$FolderRelativeUrl, 

  [Parameter(Mandatory=$True)]
  [System.IO.FileInfo]$LocalFile

)

    try {
       $fileUrl = $FolderRelativeUrl + "/" + $LocalFile.Name
       [Microsoft.SharePoint.Client.File]::SaveBinaryDirect($Web.Context, $fileUrl, $LocalFile.OpenRead(), $true)
    }
    finally {
       #$fileStream.Close()
    }
}




function Upload-Files()
{

Param(
  [Parameter(Mandatory=$True)]
  [String]$Url,

  [Parameter(Mandatory=$True)]
  [String]$UserName,

  [Parameter(Mandatory=$False)]
  [String]$Password, 

  [Parameter(Mandatory=$True)]
  [String]$TargetListTitle,

  [Parameter(Mandatory=$True)]
  [String]$SourceFolderPath

)

    if($Password) {
       $SecurePassword = $Password | ConvertTo-SecureString -AsPlainText -Force
    }
    else {
      $SecurePassword = Read-Host -Prompt "Enter the password" -AsSecureString
    }
    $Context = New-Object Microsoft.SharePoint.Client.ClientContext($Url)
    $Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName,$SecurePassword)
    $Context.Credentials = $Credentials


    $web = $Context.Web 
    $Context.Load($web)
    $list = $web.Lists.GetByTitle($TargetListTitle);
    $Context.Load($list.RootFolder)
    $Context.ExecuteQuery()


    Get-ChildItem $SourceFolderPath -Recurse | % {
       if ($_.PSIsContainer -eq $True) {
          $folderUrl = $_.FullName.Replace($SourceFolderPath,"").Replace("\","/")   
          if($folderUrl) {
             Ensure-Folder -Web $web -ParentFolder $list.RootFolder -FolderUrl $folderUrl
          }  
       }
       else{
          $folderRelativeUrl = $list.RootFolder.ServerRelativeUrl + $_.DirectoryName.Replace($SourceFolderPath,"").Replace("\","/")  
          Upload-File -Web $web -FolderRelativeUrl $folderRelativeUrl -LocalFile $_ 
       }
    }
}

Source: Gist

Usage

$Url = "https://contoso.sharepoint.com"
$UserName = "[email protected]"
$Password = "password"
$TargetListTitle = "Documents"   #Target Library
$SourceFolderPath = "C:\Users\me\Upload"  #Source Physical Path 


#Upload files
Upload-Files -Url $Url -UserName $UserName -Password $Password -TargetListTitle $TargetListTitle -SourceFolderPath $SourceFolderPath

Key points:

  • Preserve folder structure