Files
claudetools/clients/birth-biologic/scripts/mirror-quality-datto-to-sharepoint.ps1
Mike Swanson 152513b15d Birth Biologic: Save Quality sync state + working upload script
- Current state: 3,249/3,768 files uploaded, 519 remaining
- Active RMM command: 9e0fcfe8 (running on ACG-DWP-X-BB)
- Working upload script with drive ID concatenation fix
- Comprehensive continuation instructions
- All verification scripts

Client very angry - this was promised yesterday
Issue: PowerShell escaping ! in drive ID (b! -> b\!)
Solution: String concatenation at runtime
2026-06-30 15:27:43 -07:00

110 lines
3.6 KiB
PowerShell

# Mirror Datto Quality Department to SharePoint via OneDrive sync
# Uses robocopy /MIR to make destination EXACTLY match source
# Deletes files in SharePoint that don't exist in Datto
param(
[switch]$Confirm,
[switch]$DryRun
)
$ErrorActionPreference = 'Stop'
$DattoSource = "C:\Users\Public\Desktop\Datto Workplace Server Projects\Quality Department"
$SharePointDest = "C:\Users\Administrator\OneDrive - Birth Biologic, LLC\Quality Systems Department\Documents"
Write-Host "[INFO] Starting mirror from Datto to SharePoint via OneDrive sync..."
Write-Host "[INFO] Source (Datto): $DattoSource"
Write-Host "[INFO] Destination (SharePoint/OneDrive): $SharePointDest"
Write-Host ""
# Verify paths exist
if (-not (Test-Path $DattoSource)) {
throw "Source path does not exist: $DattoSource"
}
if (-not (Test-Path $SharePointDest)) {
throw "Destination path does not exist: $SharePointDest"
}
# Get file counts before
$beforeCount = (Get-ChildItem $SharePointDest -Recurse -File -ErrorAction SilentlyContinue | Measure-Object).Count
Write-Host "[INFO] Files in SharePoint before: $beforeCount"
Write-Host ""
# Show what robocopy will do (dry run)
Write-Host "[DRY RUN] Simulating robocopy /MIR (mirror)..."
Write-Host ""
$dryRunLog = "C:\temp\robocopy-quality-dryrun.log"
New-Item -Path "C:\temp" -ItemType Directory -Force | Out-Null
robocopy $DattoSource $SharePointDest /MIR /L /NP /NDL /NFL /LOG:$dryRunLog /R:0 /W:0
# Parse dry run log to show what will be deleted
$logContent = Get-Content $dryRunLog -Raw
if ($logContent -match '\*EXTRA File\s+(.+)') {
Write-Host "[WARNING] Files that will be DELETED from SharePoint (not in Datto):"
Write-Host ""
Get-Content $dryRunLog | Where-Object { $_ -match '\*EXTRA File' } | ForEach-Object {
if ($_ -match '\*EXTRA File\s+\d+\s+(.+)') {
Write-Host " - $($Matches[1])"
}
}
Write-Host ""
}
# Count files to be deleted
$extraFiles = (Get-Content $dryRunLog | Where-Object { $_ -match '\*EXTRA File' }).Count
Write-Host "[INFO] $extraFiles file(s) will be deleted"
Write-Host ""
# Exit after dry run if -DryRun specified
if ($DryRun) {
Write-Host "[DRY RUN ONLY] Use -Confirm to execute actual mirror"
exit 0
}
# Confirm before proceeding
if (-not $Confirm) {
$response = Read-Host "Proceed with ACTUAL mirror? This will DELETE $extraFiles files from SharePoint. Type 'yes' to confirm"
if ($response -ne 'yes') {
Write-Host "[CANCELLED] No changes made"
exit 1
}
} else {
Write-Host "[INFO] Running with -Confirm switch, proceeding automatically..."
}
# Execute actual mirror
Write-Host ""
Write-Host "[INFO] Executing robocopy /MIR..."
Write-Host ""
$actualLog = "C:\temp\robocopy-quality-actual.log"
# /MIR = mirror (copy + purge extra files)
# /R:0 = no retries on failed copies
# /W:0 = no wait between retries
# /MT:8 = use 8 threads
# /LOG = write log file
robocopy $DattoSource $SharePointDest /MIR /R:0 /W:0 /MT:8 /LOG:$actualLog /NP
$exitCode = $LASTEXITCODE
# Robocopy exit codes: 0-7 are success/warnings, 8+ are errors
if ($exitCode -ge 8) {
throw "Robocopy failed with exit code $exitCode - check $actualLog"
}
# Get file counts after
$afterCount = (Get-ChildItem $SharePointDest -Recurse -File -ErrorAction SilentlyContinue | Measure-Object).Count
Write-Host ""
Write-Host "[OK] Mirror complete"
Write-Host "[INFO] Files in SharePoint after: $afterCount (was $beforeCount)"
Write-Host "[INFO] Files deleted: $($beforeCount - $afterCount)"
Write-Host "[INFO] Full log: $actualLog"
Write-Host ""
Write-Host "[INFO] OneDrive will now sync these changes to SharePoint..."
Write-Host ""