1

I am trying to write a script using Power Shell to copy an entire Directory (Main Folders, Sub-Folders, and all Files in between) on a Network Share to SharePoint online. The most I have accomplished is creating the first layer. The Directory folder is uploaded just fine to my documents library on SharePoint. Next, I have been able to create the first layer consisting of the Main Folders and all files under the Directory Folder. However, I have not been able to upload any of the sub-folders or files that correspond with the Main Folders. Any assistance will be greatly appreciated. The code I am working with is below:

#Upload file

Function ImportFiles()

{

#Get name of directory
$NewDirectory = Split-Path $Directory -Leaf

#upload directory to sharepoint
$UploadNewDirectory = $List.RootFolder.Folders.Add($NewDirectory)
$Context.Load($UploadNewDirectory)
$Context.ExecuteQuery()

$FoldersInDirectory = Get-ChildItem $Directory

#upload full directory contents to sharepoint

    Foreach ($Item in $FoldersInDirectory)
    {

        if($Item | ? {$_.PsIsContainer -eq $true})
        {
            $Folder = $Item
            $UploadFoldersInDirectory = $UploadNewDirectory.Folders.Add($Folder)
            $Context.Load($UploadFoldersInDirectory)
            $Context.ExecuteQuery()

            $SubFoldersInFolder = Get-ChildItem $FoldersInDirectory

            Foreach ($SubItem in $SubFoldersInFolder)
            {
                if($SubItem | ? {$_.PsIsContainer -eq $true})
                {
                    $SubFolder = $SubItem
                    $UploadSubFoldersInDirectory = $UploadFoldersInDirectory.Folders.Add($SubFolder)
                    $Context.Load($UploadSubFoldersInDirectory)
                    $Context.ExecuteQuery()
                }

            }
        }

        elseif($Item | ? {$_.PsIsContainer -eq $false})
        {
            $File = $Item
            $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 = $UploadNewDirectory.Files.Add($FileCreationInfo)
            $Context.Load($Upload)
            $Context.ExecuteQuery()
        }

    }

} # end function ImportFiles ImportFiles

2 Answers 2

0

Approach 1:

We can use the below CSOM PowerShell script:

<#
DESCRIPTION
This script can be useful to update a specific field on a library located on a Sharepoint Online tenant
You need to know 5 mandatory parameters:
    - url_sharepoint         : the URL for root site collection
    - library                : the name of the destination library
    - url_site               : the relative path of the site

CopyRight
This script can be used as it is or can be changed based on your needs. For more details please feel free to contact me
Romeo Donca, February 2017
[email protected]
http://www.romeodonca.ro
#>

param(
[Parameter(Mandatory=$true,HelpMessage="The root site collection URL")][string]$url_sharepoint,
[Parameter(Mandatory=$true,HelpMessage="The relative path for the site site URL ___ /sites/subsite")][string]$url_site,
[Parameter(Mandatory=$true,HelpMessage="The name for the library")][string]$library
)
$t1  = get-date
$source_folder = ((new-object -com Shell.Application).BrowseForFolder(0, "Select the source folder", 0, "")).Self.Path
$source_folder
$url = $url_sharepoint+$Url_site

cls
Add-Type -Path "your_path\Microsoft.SharePoint.Client.dll"
Add-Type -Path "your_path\Microsoft.SharePoint.Client.Runtime.dll"
Import-Module MSOnline
$global:cred1 = Get-Credential
$clientContext = New-Object Microsoft.SharePoint.Client.ClientContext($url)
$cred = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($cred1.username, $cred1.Password) 
$clientContext.Credentials = $cred
$web = $clientContext.Web
$clientContext.Load($web)
$clientContext.ExecuteQuery()
($web.Lists).Count
$mylist = $web.GetList($url+"/"+$library)
$clientContext.Load($mylist)
$clientContext.ExecuteQuery()
###################### get folders existing  in the SOURCE
$directories= @()
foreach ($file in (Get-ChildItem  -Recurse -Path $source_folder -Attributes Directory))
{
    ($file.FullName.ToLower()).replace($source_folder.ToLower()+'\','')
    $directories +=($file.FullName.ToLower()).replace($source_folder.ToLower()+'\','')
}
foreach ($directory in $directories)
{
    $myfolder = $mylist.RootFolder
    $clientContext.Load($myfolder)
    $clientContext.ExecuteQuery()
    $myfolder = $myfolder.Folders.Add($directory.split('\')[0])
    $clientContext.Load($myfolder)
    $clientContext.ExecuteQuery()
    for ($i = 1; $i -le ($directory.split('\').Count-1) ; $i++)
    {
        #$directory.split('/')[$i]
        $myfolder = $myfolder.folders.Add(($directory.split('\'))[$i])
        $clientContext.Load($myfolder)
        $clientContext.ExecuteQuery()
    }
}
cls
$t1  = get-date
$i=1
$count = ((Get-ChildItem -File  -Recurse -Path $source_folder) | Measure-Object -Property FullName ).Count
foreach ($file in (Get-ChildItem -File  -Recurse -Path $source_folder))
{
    $t01  = get-date
    $url_dest = $url_sharepoint+$Url_site+'/'+$library+(($file.FullName.ToLower()).Replace($source_folder.ToLower(),'')).Replace('\','/')
    $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 = $url_dest
    $Upload = $mylist.RootFolder.Files.Add($FileCreationInfo)
    $listItem = $upload.ListItemAllFields
    $listItem['Title']=($file.Name).split('.')[0]
    Write-Host " Uploading file $i/$count $url_dest"
    $listItem.update()
    $clientContext.Load($Upload)
    $clientContext.ExecuteQuery()
    $t02  = get-date
    $speed ="{0:n2}" -f ($file.Length/($t02-$t01).TotalSeconds/1mb)
    Write-Host "...................upload speed was " $speed " MB/sec"
    $i++
}
$t2=get-date
$size = "{0:n2}" -f (gci -path $source_folder -recurse | measure-object -property length -sum).sum
cls
$speed ="{0:n2}" -f ($size/($t2-$t1).TotalSeconds/1mb)
Write-Host "Medium upload speed was " $speed " MB/sec"

Script Reference:

Upload local folder structure with files on Sharepoint Online with Powershell and CSOM

Approach 2:

Rather going with the coding approach we can go with the SharePoint Migration Tool(SPMT) - this is free version, we can download it from the below location:

Download and install the SharePoint Migration Tool

0

Try this

$urlofsite = ""https://YourSite"
$pathtothefolder = "$PathToLocalFolder"
$username = "$(Username)"
$password = "$(Password)"


$Folder = $pathtothefolder

$temrootfolder = $folder.Replace("\\", "\")
$rootfolder = $temrootfolder.Replace("/", "\")
$ParentFolder = "SiteAssets"

Function UploadFiles($path) {

    $files = Get-ChildItem $path -exclude *.zip | Where-Object { $_.FullName -notmatch ".git" -and $localfilelink -notmatch "_git" } 
    foreach ($file in $files) {  
        if ($file.GetType().Name -eq "DirectoryInfo") {
            $foldername = $file.Name
            $parent = $file.Parent.FullName
            $parent1 = $parent + "\"
            If ($parent1 -eq $Folder) {
                Add-PnPFolder -Name $foldername -folder $ParentFolder -ErrorAction SilentlyContinue
            }
            Else {
                $temproot = ""
                $temproot = $rootfolder.Replace("\", "\\")
                $Urlpath1 = ($parent -split "$temproot" )[1]
                $foldernames1 = $Urlpath1
                if ($foldernames1 -like "*\*") {
                    $foldername1 = $foldernames1.Replace("\", "/")
                }
                Else {
                    $foldername1 = $foldernames1
                }
                $fnPath = $ParentFolder + "/" + $foldername1
                Add-PnPFolder -Name $foldername -folder $fnPath -ErrorAction SilentlyContinue
            }

            $Folderpath1 = $file.FullName

            UploadFiles  $Folderpath1
        }
        Else {

            $filepath = [System.IO.Path]::GetDirectoryName($file.FullName)
            $temproot = ""
            $temproot = $rootfolder.Replace("\", "\\")
            $Urlpath = ($filepath -split "$temproot" )[1]
            $foldernames = $Urlpath
            if ($foldernames -like "*\*") {
                $foldername = $foldernames.Replace("\", "/")
            }
            Else {
                $foldername = $foldernames
            }   
            $fn = $ParentFolder + "/" + $foldername
            Write-Host $File.Name
            $file = Add-PnPFile -Path $File.FullName -Folder $fn -Checkout -Publish -PublishComment "$(Release.ReleaseName)"
            $fn = $null
        }
    }
}
UploadFiles -path $Folder
Write-Host "EOF-DeploymentComplete"

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.