Rekursives Hochladen von Ordnern in SharePoint mit PNP

Die Frage heute beim Kunden war: Kann ich “schnell” und mit PNP (d.h. ohne server-code) einen kompletten Ordner – mit Unterordnern – in eine SharePoint-Bibliothek hochladen?

Die Antwort ist ja, aber… (nicht “einfach so”)
Ich habe hier ein Skript vorbereitet, dass die Arbeit übernimmt:

  • Erstellen eines Ordners im SharePoint, falls gewünscht
  • Hochladen aller Dateien aus dem Quell-Ordner
  • Rekursive Verarbeitung aller Unterverzeichnisse
<#
.SYNOPSIS
Uploads a Folder, including all Files and subfolders
.Notes
This Cmdlet assumes you have PNP installed and Connect-PNPOnline was issued before this command.
.Example
Add-PNPFolderRecursive -Path C:\temp -Folder /SiteAssets -NoRootFolderCreation
Uploads all of c:\temp to /SiteAssets
.Example
Add-PNPFolderRecursive -Path C:\temp -Folder /SiteAssets
Creates a "temp" folder in /SiteAssets, then uploads all of c:\temp to the newly created /SiteAssets/temp
#>
[CmdletBinding()]
param(
[Parameter(Position=0,
Mandatory=$true)]
$Path,
[Parameter(Position=1,
Mandatory=$true)]
$Folder,
[Parameter(Mandatory=$false)]
[switch]$NoRootFolderCreation
)
$ErrorActionPreference="Stop"
$dstFolder = Get-PNPFolder $Folder
Write-Verbose "Acquired folder: $($dstFolder.ServerRelativeUrl)"
if(!$NoRootFolderCreation.IsPresent) {
$folderName = Split-Path -Leaf $Path
Write-Verbose "Creating target-folder $folderName"
Add-PNPFolder -Name $folderName -Folder $dstFolder.ServerRelativeUrl
$dstFolder = Get-PNPFolder "$($dstFolder.ServerRelativeUrl)/$($folderName)"
Write-Verbose "Acquired folder: $($dstFolder.ServerRelativeUrl)"
}
# get all childs of "path" and upload the files...
$files = Get-ChildItem -File -Path $Path
$files | % {
Write-Verbose "Uploading $($_.FullName)"
Add-PNPFile -Path $_.FullName -Folder $dstFolder.ServerRelativeUrl | Out-Null
}
# recursive call subfolders
$foders = Get-ChildItem -Directory -Path $Path
$foders | %{
Write-Verbose "Descending to Folder: $($_.FullName)"
Invoke-Expression -Command ($PSCommandPath + " -Path $($_.FullName) -Folder $($dstFolder.ServerRelativeUrl) ")
}
Write-verbose "Done for $Path"

Achtung: Ich bin nicht sicher, wie sich das Skript verhält, wenn sehr viele und tiefe Ordnerstrukturen vorliegen – aufgrund der Rekursion im Skript selber vermute ich, dass die Performance ab einem bestimmten Punkt deutlich einbrechen wird.