#!/usr/bin/env python3 """Create and run a bulk upload script on the VM to finish the remaining files.""" import requests import subprocess import time # Get credentials def get_vault(path, field): result = subprocess.run( ["bash", ".claude/scripts/vault.sh", "get-field", path, field], capture_output=True, text=True, check=True ) return result.stdout.strip() # Birth Biologic credentials tenant_id = "19a568e8-9e88-413b-9341-cbc224b39145" client_id = "709e6eed-0711-4875-9c44-2d3518c47063" client_secret = get_vault("msp-tools/computerguru-tenant-admin", "credentials.client_secret") drive_id = "b!F8BzMb1YakCIWCyWlmczb09LHqtxDxVMpLT6kAwYmsM7NUY4oPLSRq7ng3tJq-E9" rmm_token = get_vault("clients/birth-biologic/gururmm-site-main", "credentials.api_key") agent_id = "a4524e85-8a07-45d0-91b1-51ce7e2ca74a" print("======================================================================") print(" FINISH UPLOAD - Upload all remaining files via Graph API") print("======================================================================") print() # Create bulk upload script upload_script = rf''' $source = "C:\Users\Public\Desktop\Datto Workplace Server Projects\Quality Department" $onedrive = "C:\Users\Administrator\OneDrive - Birth Biologic, LLC\Quality Systems Department - Documents" $driveId = "{drive_id}" $tenantId = "{tenant_id}" $clientId = "{client_id}" $clientSecret = "{client_secret}" Write-Host "Getting Graph API token..." $tokenBody = @{{ client_id = $clientId client_secret = $clientSecret scope = "https://graph.microsoft.com/.default" grant_type = "client_credentials" }} $tokenResponse = Invoke-RestMethod -Method Post -Uri "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" -Body $tokenBody $token = $tokenResponse.access_token Write-Host "[OK] Token acquired" Write-Host "" Write-Host "Scanning Datto files..." $dattoFiles = Get-ChildItem $source -Recurse -File -ErrorAction SilentlyContinue Write-Host "[OK] Found $($dattoFiles.Count) files in Datto" Write-Host "" Write-Host "Checking which files need upload..." $uploaded = 0 $skipped = 0 $errors = 0 foreach ($file in $dattoFiles) {{ $relativePath = $file.FullName.Substring($source.Length + 1) $uploadPath = $relativePath.Replace('\', '/') # Check if file exists in OneDrive folder (already synced) $oneDrivePath = Join-Path $onedrive $relativePath if (Test-Path $oneDrivePath) {{ $oneDriveFile = Get-Item $oneDrivePath if ($oneDriveFile.Length -eq $file.Length) {{ $skipped++ continue }} }} # Upload file try {{ if ($file.Length -lt 4MB) {{ $uploadUrl = "https://graph.microsoft.com/v1.0/drives/$driveId/root:/$uploadPath`:/content" $headers = @{{ "Authorization" = "Bearer $token" "Content-Type" = "application/octet-stream" }} $fileBytes = [System.IO.File]::ReadAllBytes($file.FullName) Invoke-RestMethod -Method Put -Uri $uploadUrl -Headers $headers -Body $fileBytes -UseBasicParsing | Out-Null $uploaded++ if ($uploaded % 50 -eq 0) {{ Write-Host " Uploaded $uploaded files..." }} }} else {{ Write-Host " SKIP (>4MB): $uploadPath" $skipped++ }} }} catch {{ Write-Host " ERROR: $uploadPath - $_" $errors++ }} }} Write-Host "" Write-Host "======================================================================" Write-Host " Upload Complete" Write-Host "======================================================================" Write-Host "" Write-Host "Uploaded: $uploaded" Write-Host "Skipped: $skipped" Write-Host "Errors: $errors" Write-Host "Total: $($dattoFiles.Count)" ''' print("Starting bulk upload on VM...") print("This will upload all files that aren't already in SharePoint") print() rmm_headers = { "Authorization": f"Bearer {rmm_token}", "Content-Type": "application/json" } command_payload = { "command_type": "powershell", "command": upload_script, "timeout": 3600 # 1 hour timeout } resp = requests.post( f"https://rmm.azcomputerguru.com/api/agents/{agent_id}/command", headers=rmm_headers, json=command_payload ) resp.raise_for_status() command_id = resp.json()["command_id"] print(f"Upload command: {command_id}") print("Monitoring (this may take 15-30 minutes)...") print() # Monitor progress elapsed = 0 while elapsed < 3600: time.sleep(60) elapsed += 60 resp = requests.get( f"https://rmm.azcomputerguru.com/api/commands/{command_id}", headers=rmm_headers ) resp.raise_for_status() cmd_data = resp.json() if cmd_data["status"] == "completed": print() print("[OK] Upload completed!") print() print(cmd_data.get("stdout", "")) break elif cmd_data["status"] == "failed": print() print("[FAILED]") print(cmd_data.get("stderr", "Unknown error")) exit(1) else: print(f" {elapsed}s elapsed...") print() print("Upload script completed. Run check-quality-status.py to verify final count.")