How to copy a network share directory to SharePoint online using Power Shell
-
08-02-2021 - |
문제
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
해결책
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
romeodonca@outlook.com
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:
다른 팁
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"