Files
claudetools/clients/birth-biologic/session-logs/2026-06/2026-06-26-mike-birthbio-mail-migration-and-datto-vm.md
Mike Swanson 6d65bff791 sync: auto-sync from GURU-5070 at 2026-06-26 06:29:48
Author: Mike Swanson
Machine: GURU-5070
Timestamp: 2026-06-26 06:29:48
2026-06-26 06:30:46 -07:00

15 KiB

User

  • User: Mike Swanson (mike)
  • Machine: GURU-5070
  • Role: admin

Session Summary

Worked two BirthBiologic migrations in parallel: the Datto Workplace → SharePoint migration and a new Google Workspace → M365 mail migration. The Datto/SharePoint thread started as a "verify current state" task but Mike clarified the migration host is a Jupiter VM, not BB-SERVER. Located it as the libvirt domain "Windows Server 2016" (actual Windows hostname ACG-DWP-X-BB, actually Server 2019 build 17763) — an ACG-owned migration box running Datto Workplace Server + SPMT, not enrolled in RMM and sitting on an APIPA address (no LAN). Diagnosed: host bridging was fine (vnet14 enslaved to br0, carrier up); the guest simply wasn't getting a DHCP lease from pfSense after ~2 months parked. Fixed with a static IP (172.16.3.45/22), installed the GuruRMM agent (enrolled under BirthBiologic / Main Office), and confirmed Datto Workplace Server reconnected and is re-syncing. Established (via the qemu guest agent and SPMT job storage) that the April 2026 migration only completed Supply Management (160 files, custom script) + ITSvcs (excluded); the four large folders (Admin 5.8 GB, Donor Services 109 GB, Quality 28 GB, Activity Reports) were SPMT's job and last ran 2026-04-29 — completion still unconfirmed. Per Mike, full reconciliation waits until Datto finishes re-syncing.

The larger thread was standing up the Google Workspace → M365 mail migration end-to-end. Confirmed the Google super-admin (sysadmin@birthbiologic.com) lives in 1Password (Clients vault item "Google"); read it via the SOPS-vaulted 1Password service-account token and mirrored it into SOPS. Onboarded BirthBio's tenant for Exchange Operator (already had Tenant Admin consented, so the suite was provisioned programmatically — Exchange Operator SP created + Exchange Administrator role). Pulled the authoritative Google roster via domain-wide delegation (20 accounts: 15 active, 5 suspended), reconciled against M365, and surfaced two active accounts not on Mike's list (Dr. Chris Gillis medicaldirector@, Michael Merritt mmerritt@) plus an address mismatch (Mindi is mindim@ in Google, mmaher@ in M365).

Provisioned the M365 target side to Mike's licensing rules: active-12 → Business Premium (assigned BP to Mei Mei + Valerie, freed Savanna's BP by moving her to Exchange-only); created Gillis + Merritt with Exchange-only and vaulted their passwords; licensed the 4 disabled former employees with Exchange-only (kept sign-in disabled) as future shared-mailbox targets. License math closed exactly: 14 Business Premium + 7 Exchange Online Plan 1, all consumed.

Hit a real blocker creating the Gmail migration endpoint: Google returned unauthorized_client … not authorized for any of the scopes requested. Root cause = the DWD grant had only 3 of Microsoft's required 5 scopes (missing m8/feeds and gmail.settings.sharing); Google rejects the migration token all-or-nothing. Verified the exact 5-scope string against live MS Learn + a Grok live-search cross-check (Gemini CLI was down on this box), updated our runbook, and Mike re-authorized all 5 in the BB Google console. After that the endpoint (BB-Gmail) created cleanly and Batch 1 (14 live mailboxes, mail + calendar + contacts) was created and auto-started — Status: Syncing.

Key Decisions

  • Datto VM gets a static IP (172.16.3.45), not a pfSense DHCP fix. The fault was pfSense not leasing this MAC after a long park; a static on the ACG server range (172.16.3.x) is the reliable, convention-consistent fix. Follow-up: add a pfSense reservation or confirm it's outside the DHCP pool.
  • Enrolled the Datto VM under BirthBiologic / Main Office (not AZ Computer Guru) since the box exists solely for BirthBio's migration and we had that site key; reversible (agents can be moved).
  • Former employees migrate to shared mailboxes via a temp Exchange-only license (migrate into a licensed mailbox → convert to shared ≤50 GB = free → reclaim license). Source Google accounts must be un-suspended during migration (Gmail API can't read suspended accounts).
  • Licensing tiers (Mike's rules): active-users-list → Business Premium; live Google accounts not yet in M365 (Gillis, Merritt) → Exchange-only ("E1" = Exchange Online Plan 1); formers → Exchange-only (reclaimable). operations@ stays BP through migration. Existing BP users left on BP (not downgraded).
  • Batch sequencing: live users first (Batch 1); formers as Batch 2 after un-suspending them in Google and freeing Workspace seats by suspending already-migrated live users.
  • Mindi mapped via the CSV Username column (EmailAddress=mmaher@, Username=mindim@) — the proper MS mechanism — plus a belt-and-suspenders mindim@ proxy on her mailbox.
  • Target delivery domain = birthbiologic.onmicrosoft.com for Batch 1 (no routing subdomain exists; acceptable for a near-term cutover; MS prefers a subdomain for long coexistence).
  • Drove Exchange via REST InvokeCommand (Exchange Operator app token) — the EXO PowerShell module isn't installed and the app has no vaulted cert, so app-only Connect-ExchangeOnline wasn't available.

Problems Encountered

  • Datto VM on APIPA (no LAN). Host bridging fine; pfSense wasn't leasing the MAC. Fixed with static 172.16.3.45/22, GW 172.16.0.1, DNS 172.16.0.1+1.1.1.1. Verified gateway/internet/DNS + RMM check-in.
  • vault.sh get-field returned null (len 4) for nested secrets until the field arg used dotted path: credentials.client_secret, credentials.credential. Plain leaf names don't resolve.
  • SPB skuId mismatch. The scope doc's BP GUID (cbdc14ab-d96c-4132-b7f4-1f3a3a819bb4) was stale; the tenant's real SPB skuId is cbdc14ab-d96c-4c30-b9f4-6ada7cdc1d46. License assign 400'd until corrected.
  • License seat propagation lag — Valerie's BP assign 400'd ("no available licenses") immediately after freeing Savanna's seat; succeeded on retry seconds later.
  • proxyAddresses read-only via Graph — adding Mindi's alias required Exchange Set-Mailbox (EXO), not a Graph PATCH.
  • Gmail migration endpoint failed: unauthorized_client … not authorized for any of the scopes requested. DWD had 3 of 5 required scopes. Got the verbatim 5-scope string from MS Learn + Grok; Mike re-authorized; endpoint then created.
  • onboard365.sh vault path — looked at /c/Users/guru/.claude/identity.json; fixed by exporting VAULT_ROOT_ENV=/d/vault (logged as friction).
  • GCP API enable initially run as the wrong identity — Mike first ran gcloud services enable as sysadmin@birthbiologic.com (no rights to ACG's project); succeeded once run as the ACG owner of acg-msp-access.
  • Gemini CLI down (throwIneligibleOrProjectIdError, needs interactive re-login) — used Grok for the live-doc cross-check instead. Logged to errorlog.

Configuration Changes

  • ACG-DWP-X-BB (Jupiter "Windows Server 2016" VM): static IP 172.16.3.45/22, GW 172.16.0.1, DNS 172.16.0.1 + 1.1.1.1 (persistent). GuruRMM agent installed (universal installer), enrolled BirthBiologic / Main Office, agent a4524e85-8a07-45d0-91b1-51ce7e2ca74a.
  • BirthBio M365 tenant (19a568e8-…): onboarded Exchange Operator (+ Defender Add-on) SPs via onboard365.sh provision; roles assigned (Exchange Admin on Exchange Operator + Security Investigator, CA Admin on Tenant Admin, User Admin + Auth Admin on User Manager).
    • License changes: Mei Mei (msenthavy) +BP; Valerie (vvaneaton) +BP; Savanna (sabron) BP→EXO; created medicaldirector@ (Gillis) +EXO and mmerritt@ (Merritt) +EXO; licensed aboutte, araso, khoffman, pnelson with EXO (kept sign-in disabled).
    • Set-Mailbox mmaher@ added secondary smtp:mindim@birthbiologic.com.
    • Created Gmail migration endpoint BB-Gmail; created + auto-started migration batch BB-Batch1 (14 users, TargetDeliveryDomain birthbiologic.onmicrosoft.com, NotificationEmails sysadmin@).
  • Vault (pushed): clients/birth-biologic/google-workspace.sops.yaml, clients/birth-biologic/m365-medicaldirector.sops.yaml, clients/birth-biologic/m365-mmerritt.sops.yaml.
  • Repo: updated projects/msp-tools/runbooks/google-workspace-to-m365-migration.md (exact 5-scope string + all-or-nothing gotcha + Contacts-API-retired/People-API + GCP-owner notes).
  • errorlog.md: gemini CLI failure entry (+ onboard365 vault-path friction).

Credentials & Secrets

  • Google Workspace super-admin sysadmin@birthbiologic.com (source tenant) — sourced from 1Password Clients vault item "Google"; mirrored to SOPS clients/birth-biologic/google-workspace.sops.yaml (credentials.password, 19 chars). Used for admin.google.com console (DWD/API) + as the migration impersonation admin.
  • M365 mailbox — Dr. Chris Gillis medicaldirector@birthbiologic.com — created this session; password vaulted at clients/birth-biologic/m365-medicaldirector.sops.yaml (forceChangePasswordNextSignIn=true).
  • M365 mailbox — Michael Merritt mmerritt@birthbiologic.com — created this session; password vaulted at clients/birth-biologic/m365-mmerritt.sops.yaml (forceChangePasswordNextSignIn=true).
  • App secrets used (already vaulted): Tenant Admin msp-tools/computerguru-tenant-admin (credentials.client_secret); Exchange Operator msp-tools/computerguru-exchange-operator (credentials.client_secret); Google SA msp-tools/acg-msp-access-google-workspace (credentials.credential, full JSON); 1Password service token infrastructure/1password-service-account.sops.yaml.

Infrastructure & Servers

  • ACG-DWP-X-BB — Jupiter libvirt domain "Windows Server 2016" (actually WS2019, build 17763). Windows hostname ACG-DWP-X-BB. NIC virtio 52:54:00:d4:8e:59 on br0 (vnet14). Static 172.16.3.45/22. Runs Datto Workplace Server (svc datto_workplace_server.default, proc WorkplaceServer) + SPMT (under Administrator profile). RMM agent a4524e85-8a07-45d0-91b1-51ce7e2ca74a. Datto source tree C:\Users\Public\Desktop\Datto Workplace Server Projects.
  • Jupiter 172.16.3.20 (Unraid, virsh host). LAN 172.16.0.0/22, GW pfSense 172.16.0.1. guest-exec helper at /root/gx.sh on Jupiter.
  • BB-SERVER — RMM agent 6c02baa7-0f1c-4990-b466-c9ab9eaefd3b. Also has Datto Workplace Server + the original custom-script artifacts at C:\GuruMigration (bb-migration-state.json shows 160 Supply Mgmt + 49 ITSvcs uploaded in April).
  • BirthBio M365 tenant birthbiologic.com / 19a568e8-9e88-413b-9341-cbc224b39145.
    • SPs: Tenant Admin 7a199b11-97fb-4e65-917d-f8d29a53ba49; Exchange Operator bab4699b-32a3-4434-9cad-7a4a08cc4d9e; Security Investigator bf684a4b-…; User Manager 3347ebcc-…; Defender Add-on 161b8f61-…. New user objects: Gillis 1bd491e1-3ba6-4214-8c6d-46426f8681da, Merritt 117a3367-cd5f-4565-af11-af5ff089224f.
    • SKUs: Business Premium (SPB) cbdc14ab-d96c-4c30-b9f4-6ada7cdc1d46 (14/14); Exchange Online Plan 1 (EXCHANGESTANDARD) 4b9405b0-7788-4568-add1-99614e613b69 (7/7). Accepted domains: birthbiologic.com (default), birthbiologic.onmicrosoft.com.
  • Google project acg-msp-access (number 806899474449). SA acg-msp-access@acg-msp-access.iam.gserviceaccount.com, OAuth2 client ID 102231607889615995452. APIs enabled: Gmail, Calendar (calendar-json), People.
  • Google roster (DWD pull): 15 active, 5 suspended. Active staff emails per clients/birth-biologic/ docs/migration/google-to-m365-scope.md; Mindi = mindim@ (Google) ↔ mmaher@ (M365).

Commands & Outputs

  • Required Google DWD scopes (exact, 5, comma-separated, no spaces): https://mail.google.com/,https://www.googleapis.com/auth/calendar,https://www.google.com/m8/feeds/,https://www.googleapis.com/auth/gmail.settings.sharing,https://www.googleapis.com/auth/contacts (m8/feeds is a still-valid alias for the contacts scope, served by People API; legacy Contacts API retired 2022, not enableable, not needed.)
  • EXO via REST: POST https://outlook.office365.com/adminapi/beta/{tenant}/InvokeCommand with Exchange Operator app token (scope=https://outlook.office365.com/.default), body {"CmdletInput":{"CmdletName":"…","Parameters":{…}}}. byte[] params (ServiceAccountKeyFileData, CSVData) passed as base64 strings.
  • New-MigrationEndpoint -Gmail -Name BB-Gmail -ServiceAccountKeyFileData <b64> -EmailAddress sysadmin@birthbiologic.com → created.
  • New-MigrationBatch -Name BB-Batch1 -SourceEndpoint BB-Gmail -CSVData <b64> -TargetDeliveryDomain birthbiologic.onmicrosoft.com -AutoStart -NotificationEmails sysadmin@ → Status=Syncing, Total=14.
  • Get-MigrationUser BB-Batch1 → 14 Provisioning, 0 skipped (normal initial state).
  • Datto source counts (ACG-DWP-X-BB): Admin 6,279/5.8GB · Donor Services 56,826/109GB · Quality 3,714/28GB · Supply Mgmt 160/33MB · Activity Reports 1 · ITSvcs 52 (excluded).

Pending / Incomplete Tasks

  • Batch 1 monitor → MX cutover. Watch BB-Batch1 Provisioning→Syncing→Synced. When Synced: flip MX in SiteGround → M365, update SPF (include:spf.protection.outlook.com), enable/publish DKIM (2 CNAMEs), autodiscover CNAME → autodiscover.outlook.com, run final delta, then complete the batch.
  • Batch 2 — 5 former employees → shared. Un-suspend each in Google (free Workspace seats by suspending migrated live users), run a Gmail batch (targets already EXO-licensed: aboutte, araso, khoffman, pnelson, sabron), then convert to shared mailboxes and reclaim the 5 EXO licenses.
  • Datto → SharePoint reconciliation. After ACG-DWP-X-BB finishes re-syncing with Datto cloud, compare source vs each SharePoint site to confirm what the April SPMT run left unfinished (Admin / Donor Services / Quality / Activity Reports).
  • pfSense: add a DHCP reservation for 172.16.3.45 (MAC 52:54:00:d4:8e:59) or confirm it's outside the pool.
  • Valerie VanEaton — active (receiving daily; last sent 2026-05-13). Julie to confirm whether the mid-May send drop-off = leave/departure; if departed, move her to the former→shared track.
  • Decisions still open: confirm Merritt's long-term tier; whether operations@ becomes shared post-migration.
  • Wiki: BirthBio article is stale (says migration incomplete / 13 mailboxes) — recompile.

Reference Information

  • Migration scope doc: clients/birth-biologic/docs/migration/google-to-m365-scope.md.
  • Runbook (updated): projects/msp-tools/runbooks/google-workspace-to-m365-migration.md.
  • MS Learn: manually-configuring-gsuite-for-migration (scope string), automated-migration-neweac, google-workspace-migration-prerequisites, perform-g-suite-migration.
  • RMM install one-liner (BirthBio site): irm https://rmm.azcomputerguru.com/install/BRIGHT-PEAK-5980/windows | iex.
  • Discord DMs to Mike: message_id 1520034139900739627 (initial DWD), 1520055625302675537 (corrected 5-scope).
  • Vault enrollment key: clients/birth-biologic/gururmm-site-main (site BRIGHT-PEAK-5980, id 3b20ef97-…).