From 986d1740343c3895d6b61e7137bd9db8f32e4135 Mon Sep 17 00:00:00 2001 From: james-enperso Date: Mon, 23 Feb 2026 14:15:58 +1100 Subject: [PATCH] Refactor SharePoint sync script for improved error handling and added multiple library support Refactor SharePoint sync script for improved error handling and added multiple library support --- .../Sync-SharepointFolder.ps1 | 152 +++++++++++++----- 1 file changed, 108 insertions(+), 44 deletions(-) diff --git a/Sync-SharepointFolder/Sync-SharepointFolder.ps1 b/Sync-SharepointFolder/Sync-SharepointFolder.ps1 index 586f63a..519ba0f 100644 --- a/Sync-SharepointFolder/Sync-SharepointFolder.ps1 +++ b/Sync-SharepointFolder/Sync-SharepointFolder.ps1 @@ -12,76 +12,140 @@ function Sync-SharepointLocation { ) try { Add-Type -AssemblyName System.Web - #Encode site, web, list, url & email [string]$siteId = [System.Web.HttpUtility]::UrlEncode($siteId) [string]$webId = [System.Web.HttpUtility]::UrlEncode($webId) [string]$listId = [System.Web.HttpUtility]::UrlEncode($listId) [string]$userEmail = [System.Web.HttpUtility]::UrlEncode($userEmail) [string]$webUrl = [System.Web.HttpUtility]::UrlEncode($webUrl) - #build the URI + $uri = New-Object System.UriBuilder $uri.Scheme = "odopen" $uri.Host = "sync" $uri.Query = "siteId=$siteId&webId=$webId&listId=$listId&userEmail=$userEmail&webUrl=$webUrl&listTitle=$listTitle&webTitle=$webTitle" - #launch the process from URI + + Write-Host "Starting sync: $webTitle - $listTitle" Write-Host $uri.ToString() - start-process -filepath $($uri.ToString()) + Start-Process -FilePath $($uri.ToString()) } catch { - $errorMsg = $_.Exception.Message + Write-Warning "Sync failed for $webTitle - $listTitle" + Write-Warning $_.Exception.Message + return $false } - if ($errorMsg) { - Write-Warning "Sync failed." - Write-Warning $errorMsg + + # Wait for sync folder with timeout + $timeout = 120 + $elapsed = 0 + while (!(Get-ChildItem -Path $syncPath -ErrorAction SilentlyContinue)) { + Start-Sleep -Seconds 2 + $elapsed += 2 + if ($elapsed -ge $timeout) { + Write-Warning "Timed out waiting for: $syncPath" + return $false + } } - else { - Write-Host "Sync completed." - while (!(Get-ChildItem -Path $syncPath -ErrorAction SilentlyContinue)) { - Start-Sleep -Seconds 2 + Write-Host "Sync completed: $syncPath" -ForegroundColor Green + return $true +} + +function Wait-ForOneDrive { + param ([int]$TimeoutSeconds = 120) + $elapsed = 0 + while (!(Get-Process OneDrive -ErrorAction SilentlyContinue)) { + Start-Sleep -Seconds 5 + $elapsed += 5 + if ($elapsed -ge $TimeoutSeconds) { + Throw "OneDrive not running after ${TimeoutSeconds}s" } - return $true - } + } + # Allow time for full initialization + Start-Sleep -Seconds 10 } #endregion -#region Main Process -try { - #region Sharepoint Sync - [mailaddress]$userUpn = cmd /c "whoami/upn" - $params = @{ - #replace with data captured from your sharepoint site. + +#region Configuration +$libraries = @( + @{ + siteId = "{00000000-0000-0000-0000-000000000000}" + webId = "{00000000-0000-0000-0000-000000000000}" + listId = "{00000000-0000-0000-0000-000000000000}" + webUrl = "https://contoso.sharepoint.com/sites/Finance" + webTitle = "Finance" + listTitle = "Shared Documents" + }, + @{ + siteId = "{00000000-0000-0000-0000-000000000000}" + webId = "{00000000-0000-0000-0000-000000000000}" + listId = "{00000000-0000-0000-0000-000000000000}" + webUrl = "https://contoso.sharepoint.com/sites/HR" + webTitle = "HR" + listTitle = "Policies" + }, + @{ siteId = "{00000000-0000-0000-0000-000000000000}" webId = "{00000000-0000-0000-0000-000000000000}" listId = "{00000000-0000-0000-0000-000000000000}" - userEmail = $userUpn - webUrl = "https://example.sharepoint.com" - webTitle = "Title" - listTitle = "FolderName" + webUrl = "https://contoso.sharepoint.com/sites/Operations" + webTitle = "Operations" + listTitle = "Templates" + } +) +#endregion + +#region Main Process +Start-Transcript -Path "$env:TEMP\SharePointSync.log" -Append +try { + [mailaddress]$userUpn = cmd /c "whoami /upn" 2>$null + if (!$userUpn) { + $userUpn = (Get-ItemProperty -Path "HKCU:\Software\Microsoft\OneDrive\Accounts\Business1" -ErrorAction Stop).UserEmail } - $params.syncPath = "$(split-path $env:onedrive)\$($userUpn.Host)\$($params.webTitle) - $($Params.listTitle)" - Write-Host "SharePoint params:" - $params | Format-Table - if (!(Test-Path $($params.syncPath))) { - Write-Host "Sharepoint folder not found locally, will now sync.." -ForegroundColor Yellow - $sp = Sync-SharepointLocation @params - if (!($sp)) { - Throw "Sharepoint sync failed." + + Wait-ForOneDrive + + $oneDriveRoot = Split-Path $env:OneDrive + $results = @{ Success = @(); Failed = @(); Skipped = @() } + + foreach ($lib in $libraries) { + $lib.userEmail = $userUpn + $lib.syncPath = "$oneDriveRoot\$($userUpn.Host)\$($lib.webTitle) - $($lib.listTitle)" + + if (Test-Path $lib.syncPath) { + Write-Host "Already synced: $($lib.webTitle) - $($lib.listTitle)" -ForegroundColor Yellow + $results.Skipped += "$($lib.webTitle) - $($lib.listTitle)" + continue } + + Write-Host "Syncing: $($lib.webTitle) - $($lib.listTitle)" -ForegroundColor Cyan + $success = Sync-SharepointLocation @lib + + if ($success) { + $results.Success += "$($lib.webTitle) - $($lib.listTitle)" + } + else { + $results.Failed += "$($lib.webTitle) - $($lib.listTitle)" + } + + # Stagger syncs to avoid overwhelming OneDrive + Start-Sleep -Seconds 5 } - else { - Write-Host "Location already syncronized: $($params.syncPath)" -ForegroundColor Yellow + + # Summary + Write-Host "`n===== Sync Summary =====" -ForegroundColor Cyan + Write-Host "Synced: $($results.Success.Count)" -ForegroundColor Green + Write-Host "Skipped: $($results.Skipped.Count)" -ForegroundColor Yellow + Write-Host "Failed: $($results.Failed.Count)" -ForegroundColor Red + + if ($results.Failed.Count -gt 0) { + Write-Warning "Failed libraries: $($results.Failed -join ', ')" + Throw "One or more libraries failed to sync." } - #endregion } catch { - $errorMsg = $_.Exception.Message + Write-Warning $_.Exception.Message + Stop-Transcript + exit 1 } finally { - if ($errorMsg) { - Write-Warning $errorMsg - Throw $errorMsg - } - else { - Write-Host "Completed successfully.." - } + Stop-Transcript } -#endregion \ No newline at end of file +#endregion