Birth Biologic: Merge + save Quality sync continuation state

This commit is contained in:
2026-06-30 15:28:44 -07:00
16 changed files with 812 additions and 6 deletions

View File

@@ -0,0 +1,153 @@
## User
- **User:** Mike Swanson (mike)
- **Machine:** GURU-5070
- **Role:** admin
## Session Summary
Consolidated BirthBiologic's Quality content in SharePoint and reconciled it against the Datto
Workplace source of truth, then handled the migration-corruption fallout. The session began by
ensuring sysadmin@birthbiologic.com had access to the BirthBio SharePoint content sites: granted
owner+member on the canonical **Quality Systems Department** (QSD) site via its M365 group (he had
no access); confirmed existing owner access on Donor Services, Supply Management, and the old
Quality Department. The `[admin]` communication site and four empty `Quality Systems Department-*`
spoke sites have no M365 group, so they require a site-collection-admin grant via PnP (commands
DM'd to Mike; not runnable by the app — `Unsupported app only token` on SP REST).
Investigated why two Quality sites existed (`Quality Department`, created 2026-04-20, the original
migration landing site; `Quality Systems Department`, created 2026-06-02, canonical) and treated
Datto Workplace on ACG-DWP-X-BB as the authoritative source. Enumerated the Datto "Quality
Department" project (3,812 files / 28 GB). Reconciled QSD to Datto: removed 811 byte-identical
duplicate files (kept the Datto-aligned copy of each, verified by quickXorHash), removed 195
SP-only files older than the current week (kept 11 recent), and backfilled 31 files Datto had but
QSD lacked (30 via server-side copy from the old site, 1 — `2025.requested items for bone bank
audit.pdf` — uploaded from the Datto host via a pre-authenticated upload session). Final QSD ~3,766
files with 0 Datto files missing; the only remaining diff is 13 files under a renamed folder
(`Lab Log.2020 to Current` vs Datto's `2020 to 2024`).
Archived the duplicate site: copied the divergent `Processor Contact Information...Surgenex
8.21.24.xlsx` from the old site into QSD alongside its counterpart, ran a pre-delete safety delta
(0 unaccounted recent edits), then deleted the old `Quality Department` M365 group/site. The Tenant
Admin app 403s on group DELETE (has GroupMember write, not Group.ReadWrite.All); the **User Manager
app** performed the delete (HTTP 204). Group soft-deleted (restorable ~30 days; site recycle ~93 days).
Then handled migration corruption: the Surgenex xlsx Mike tried to open errored ("file format not
valid"). Diagnosed the byte-array->decimal-text corruption (header `80 75 3 4...` instead of
`PK\x03\x04`); the 64 KB QSD copy was corrupt, the 20 KB old-site copy clean and newer — deleted the
corrupt copy and renamed the clean one to canonical (after a WOPI lock cleared). A QSD-wide sweep
found **81 corrupt files** (60 docx/17 pdf/2 xlsx/2 doc), more than a parallel session's earlier 47
(my reconciliation propagated corrupt orphans via byte-preserving copy). Coordinated with the
parallel session (coord todo 28e3e7ab): appended reconciliation caveats + the live 81 count as
child todos, and graduated their recovery tool `bb-recover.py` from session scratchpad into the repo
at `clients/birth-biologic/scripts/`. Recovery itself remains deferred per Mike.
Finally, on a context switch, ran a read-only DC health verification on Peaceful Spirit's PST-SERVER
(192.168.0.2) via RMM: PST-SERVER healthy (all 5 FSMO, dcdiag clean, SYSVOL/NETLOGON shared, SYSVOL
Event 4602 from the 06-13 D4 restore), but PST-SERVER2 unreachable (ping fails, RPC 1722, ~16 days
stale) — Gate-4 DFSR work blocked until SERVER2 is back online.
## Key Decisions
- **Datto = source of truth** for the Quality reconciliation; the Datto-aligned path is the keeper
in any duplicate pair. Confirmed dupes removed only when a byte-identical Datto-aligned twin
remained in QSD (no unique data lost).
- **Did not bulk-delete by path.** Path comparison flagged 1,016 SP files "not in Datto," but 921
were the same files reorganized into different folders. Switched to hash-based dedup to avoid
destroying real data; surfaced this to Mike rather than executing the literal rule.
- **Backfill via server-side copy from the old site** (not Datto host upload) for 30 of 31 files —
cheaper and byte-identical; only the 1 file absent from the old site needed a host upload.
- **In-place reconstruct is the right recovery method** (the parallel session's bb-recover.py
PUTs recovered bytes to the same item id, preserving share links) — better than my re-copy
approach. Graduated their tool rather than writing a competing one.
- **Deleted the old site via the User Manager app** after the Tenant Admin app 403'd on group
delete — different app tier for the privilege.
- **Surgenex fix by swap, not reconstruct** — a clean newer copy existed on the old site, so
swapping it in was more reliable than reconstructing the corrupt bytes.
- **All destructive ops gated behind dry-runs + recycle bin** — every deletion recoverable ~93 days.
## Problems Encountered
- **Path-based "not in Datto" was misleading** — 921 of 1,016 were reorg copies; resolved by
switching to content-hash dedup.
- **Timestamp filter poisoned by migration copies** — 1,007 orphans carried today's date from my
earlier copy; used the old site's lastModified as the true-age signal instead.
- **Tenant Admin app cannot delete M365 groups** (403, GroupMember-only) and cannot manage SP site
state (`Unsupported app only token`) — used the User Manager app for group delete; SP site
lock/spoke-site grants pushed to Mike via PnP.
- **WOPI lock (HTTP 423)** blocked the Surgenex swap while the file was open in Excel; retried after
Mike closed it.
- **RMM stdout capped** the base64 of the 6.8 MB file (got 786 KB of 6.8 MB) — switched to a
pre-authenticated Graph upload session so the host PUT the bytes directly.
- **bash `${var/pat/repl}` mangled the upload URL** (& separators) — rewrote the PS script via
Python and dispatched with `jq --rawfile`.
- **Corruption scan kwarg bug** (`requests.get got multiple values for 'headers'`) — fixed the
retry wrapper to merge headers.
- **errorlog.md rebase conflict** on sync (concurrent top-prepends from another session) — resolved
keeping all entries.
- **bb-recover.py was stranded in another session's scratchpad** (session-local path) — graduated
to the repo so any machine can run it.
## Configuration Changes
- Created `clients/birth-biologic/docs/migration/2026-06-29-quality-dept-archival-plan.md` (then
marked COMPLETED).
- Created `clients/birth-biologic/scripts/bb-recover.py` (graduated recovery tool; pushed in 801ff788).
- Modified `errorlog.md` (friction: group-delete app gap; + conflict resolution).
- SharePoint (QSD, tenant 19a568e8-...): +sysadmin@ owner/member on QSD group; 811 dupes deleted;
195 stale SP-only deleted; 31 files backfilled; Surgenex corrupt copy deleted + clean copy renamed.
- Deleted old `Quality Department` M365 group/site (soft-deleted).
- Coord todos: appended children 5162f79f (caveats) + ac832238 (live 81 count) under 28e3e7ab.
## Credentials & Secrets
- No new credentials created or discovered. Used (read-only) from vault:
- `msp-tools/computerguru-tenant-admin.sops.yaml` field `credentials.client_secret` (app
709e6eed-0711-4875-9c44-2d3518c47063) — Graph app-only against BirthBio tenant.
- `msp-tools/computerguru-user-manager.sops.yaml` field `credentials.client_secret` (app
64fac46b-8b44-41ad-93ee-7da03927576c) — used for the M365 group delete (has Group.ReadWrite.All).
- bb-recover.py reads the Tenant Admin secret via env `BBSEC` (not embedded).
## Infrastructure & Servers
- **BirthBio M365 tenant:** 19a568e8-9e88-413b-9341-cbc224b39145
- **QSD site:** birthbiologic.sharepoint.com/sites/QualitySystemsDepartment (site id
...,3173c017-58bd-406a-8858-2c969667336f,...; single drive "Documents")
- **Old (deleted) group id:** f24b2e10-2d73-49d7-ab06-fe63065301d1 (QualityDepartment@), deletedDateTime 2026-06-29T22:23:15Z
- **Datto source host:** ACG-DWP-X-BB (172.16.3.45), RMM agent a4524e85-8a07-45d0-91b1-51ce7e2ca74a;
source tree `C:\Users\Public\Desktop\Datto Workplace Server Projects\Quality Department` (3,812 files)
- **Peaceful Spirit:** PST-SERVER 192.168.0.2 (all 5 FSMO, Server 2016, RMM 87293069-33b6-45e8-a68f-6811216cdb96);
PST-SERVER2 192.168.1.127/192.168.1.5 (RMM 5d2d7ba0-3903-4aa3-9e97-6ca4424ffe65) — UNREACHABLE.
## Commands & Outputs
- Graph app-only token: POST login.microsoftonline.com/{tenant}/oauth2/v2.0/token, scope
graph.microsoft.com/.default, grant client_credentials.
- Dedup keep-rule: same quickXorHash, keep copy whose path is in the Datto path set.
- Group delete: `DELETE /groups/{id}` — 403 via Tenant Admin app, **204 via User Manager app**.
- Pre-auth upload: `POST /drives/{id}/root:/{path}:/createUploadSession` -> host PUTs bytes to uploadUrl.
- DC verify (PST-SERVER): dcdiag Advertising/FSMOCheck/Services PASSED; `repadmin /replsummary`
PST-SERVER2 fails 5/5 error 1722; ping PST-SERVER2 = False.
## Pending / Incomplete Tasks
- **BirthBio QMS corruption recovery (DEFERRED, todo 28e3e7ab):** ~81 corrupt files in QSD. Run
`clients/birth-biologic/scripts/bb-recover.py birthbiologic.sharepoint.com:/sites/QualitySystemsDepartment`
(dry-run) then `--apply` (set BBSEC). Re-scan live; do NOT trust the saved 47-list. Then widen
the scan tenant-wide (Admin/Donor Services/Supply were in the same 6/26 corrupt batch).
- **Spoke + [admin] site access:** Mike to run the PnP grant (DM'd) for sysadmin@ on the 5 groupless sites.
- **Quality ticket write-up** (drafted in Mike's voice) NOT yet posted — needs ticket # (assumed
#32187), visibility (customer/internal), and billing decision.
- **Surgenex two-version note** moot now (corrupt copy removed; one clean file remains).
- **Peaceful Spirit:** PST-SERVER2 is dark — confirm whether it should be online; Gate-4 DFSR
(backlog drain, re-add folder/root targets) blocked until it is. If PST-SERVER was full-restored,
run a deeper post-restore DC pass (USN/invocationID, dcdiag /test:Replications, DNS SRV).
- **6 files** returned fetch-errors during the corruption sweep — re-check on recovery run.
## Reference Information
- Coord todos: 28e3e7ab-f77d-4d4f-b2e0-15f0254155ea (parent recovery), 5162f79f-de05-49d3-9f16-546f8d11c241
(caveats), ac832238-69f0-421f-9cc3-e9a7537d8ede (live 81 count).
- Pushed commit: 801ff788 (bb-recover.py graduation + errorlog).
- Recovery tool: clients/birth-biologic/scripts/bb-recover.py (BBSEC env = tenant-admin client_secret).
- Archival plan: clients/birth-biologic/docs/migration/2026-06-29-quality-dept-archival-plan.md
- Peaceful Spirit runbook: clients/peaceful-spirit/AD-DC2-REBUILD-RUNBOOK.md

View File

@@ -28,21 +28,21 @@
### `SG-Management-RW` → `\\CS-SERVER\Management`
**RW:** Meredith Kuhn, Ashley Jensen, Lauren Hasselman, Allison Reibschied, Megan Hiatt,
Crystal Rodriguez, Veronica Feller, Shelby Trozzi, Christina DuPras · ~~Tamra Matthews~~ *(leaving)*
Crystal Rodriguez, Veronica Feller, Shelby Trozzi, Christina DuPras · ~~Tamra Matthews~~ *(OFFBOARDED 2026-06-30)*
**RO (read-only):** Lois Lane, Christine Nyanzunda **[OPEN]**, Susan Hicks **[OPEN]**, John Trozzi, Lupe Sanchez **[OPEN]**
> No `SG-Management-RO` group exists — RO members need either a new RO group or a direct NTFS read ACL. **Decision needed.**
### `SG-Sales-RW` → `\\CS-SERVER\Sales` / `SalesDept`
**RW:** Meredith Kuhn, Ashley Jensen, Lauren Hasselman, Megan Hiatt, Crystal Rodriguez · ~~Tamra Matthews~~ *(leaving)*
**RW:** Meredith Kuhn, Ashley Jensen, Lauren Hasselman, Megan Hiatt, Crystal Rodriguez · ~~Tamra Matthews~~ *(OFFBOARDED 2026-06-30)*
**RO (`SG-Sales-RO`):** Shelby Trozzi
> **Two shares exist — `Sales` and `SalesDept`.** SalesDept holds the real history (20142026 reports, marketing). Confirm which the group maps to (or both), and what `Sales` is for.
### `SG-ALdocs-RW` → `\\CS-SERVER\ALdocs` *(share + group NOT created yet)*
**RW:** Lois Lane, Karen Rossini, Meredith Kuhn, Ashley Jensen, Megan Hiatt, Crystal Rodriguez · ~~Tamra Matthews~~ *(leaving)*
**RW:** Lois Lane, Karen Rossini, Meredith Kuhn, Ashley Jensen, Megan Hiatt, Crystal Rodriguez · ~~Tamra Matthews~~ *(OFFBOARDED 2026-06-30)*
> Must create the share + `SG-ALdocs-RW` group before assigning. Nurses (Lois/Karen) + Exec tier + Sales team.
### `SG-WebDocs-RW` → `\\CS-SERVER\WebDocs` *(share + group NOT created yet)*
**RW:** Megan Hiatt, Crystal Rodriguez, Meredith Kuhn, Ashley Jensen · ~~Tamra Matthews~~ *(leaving)*
**RW:** Megan Hiatt, Crystal Rodriguez, Meredith Kuhn, Ashley Jensen · ~~Tamra Matthews~~ *(OFFBOARDED 2026-06-30)*
> Must create the share + `SG-WebDocs-RW` group. Distinct from the retired DSM `web` station.
### `SG-Server-RW` → `\\CS-SERVER\Server`

View File

@@ -0,0 +1,43 @@
# Cascades — Printer / VLAN 20 Migration Map (GPO planning)
Living reference for the printer migration onto Staff VLAN 20 (10.0.20.0/24) and the
eventual **printer GPO** build. Update as machines/printers migrate. Started 2026-06-30 (Howard).
## How the GPO needs to be built (two layers)
1. **Point-and-Print policy (computer GPO, fleet-wide)** — REQUIRED prerequisite or any
GPO-pushed printer fails (PrintService event 513 / error 0xBCB) for standard users.
Set on `HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Printers`:
`RestrictDriverInstallationToAdministrators=0`; subkey `PointAndPrint`:
`Restricted=1, TrustedServers=1, ServerList=CS-SERVER, InForest=0,`
`NoWarningNoElevationOnInstall=1, UpdatePromptSettings=2` (scopes silent driver install
to CS-SERVER only). Caregiver machines already have this — that's why their printer GPO
works. Set manually 2026-06-30 on DESKTOP-ROK7VNM + DESKTOP-DLTAGOI; needs to be a GPO.
2. **Printer deployment** — GPP Printers / Deployed Printers mapping `\\CS-SERVER\<share>`
to the right users/OU/room. Existing GPO `CSC - Life Enrichment Printers` likely still
points at OLD share names — repoint. `CSC - Printer Deployment` is disabled/empty (do not use).
**Driver trap:** Canon MF741/743 are **UFR II only** — PCL6 produces Error #822 (spools, never
prints). Any GPO/share for those Canons MUST use `Canon Generic Plus UFR II V250` (INF cnlb0ma64.inf).
## Printer / machine map
| Printer (share / name) | Model | IP (VLAN20) | Driver | Machine | User(s) | Domain? | Status / GPO action |
|---|---|---|---|---|---|---|---|
| `\\CS-SERVER\FrontDesk` | Epson ET-5800 | 10.0.20.221 | EPSON ET-5800 Series | RECEPTIONIST-PC (frontdesk box, S/N MJ0KQHNP) | frontdesk | Domain (cascades.local) | DONE — share repointed, mapped, default. Add to GPO. |
| `\\CS-SERVER\LifeEnrichment` | Canon MF741CDW | 10.0.20.94 | Canon Generic Plus UFR II V250 | DESKTOP-DLTAGOI; DESKTOP-ROK7VNM | sharon.edwards; susan.hicks | Domain | DONE — UFR II driver fixed, mapped (not default). **Repoint `CSC - Life Enrichment Printers` GPO from old `1F-132-RecRoom-Canon` to `LifeEnrichment`.** |
| Dining Room Manager - Canon MF743CDW | Canon MF743CDW (MF741C/743C) | 10.0.20.228 | Canon Generic Plus UFR II V250 | DESKTOP-MD6UQI3 | dining manager (Alyssa) | **WORKGROUP — not domain-joined yet** | DONE as direct-IP (local) printer, default. **TODO: when DESKTOP-MD6UQI3 is domain-joined, add this printer to the GPO and map it to Alyssa's domain account.** |
| Chef Office - Brother MFC-9330CDW | Brother MFC-9330CDW | 10.0.20.236 | Brother MFC-9330CDW Printer | CHEF-PC | chef (all users) | **WORKGROUP — not domain-joined** | DONE as direct-IP (machine-wide / all users), default. **TODO: add to GPO + map to chef's domain account once CHEF-PC is domain-joined.** This is the Chef's printer in the Chef's office (distinct from the kitchen printer with the chefs). |
| Memory Care Front Desk - Epson ET-5800 (`\\CS-SERVER\MCReception`) | Epson ET-5800 | 10.0.20.78 | EPSON ET-5800 Series | MEMRECEPT-PC | memfrtdesk (+ other MemCare front-desk staff) | **WORKGROUP — not domain-joined** | Already shared on CS-SERVER as `MCReception`. Machine currently has the Epson via OLD vendor/WSD ports (`EP833571:ET-5800 SERIES` + WSD), NOT the static .78 — needs direct-IP to 10.0.20.78. **Mark for GPO: MemCare front-desk users (mostly the memfrtdesk machine). TODO: add to GPO + map to domain accounts once domain-joined.** |
| Memory Care MedTech - Brother MFC-L8900CDW (`\\CS-SERVER\MCMedTech`) | Brother MFC-L8900CDW | 10.0.20.74 | Brother MFC-L8900CDW series | RECEPTIONIST-PC (memcare box → **rename to MEMCARE-***); DESKTOP-LPOPV30 | memory care; karen rossini | **WORKGROUP** | DONE direct-IP machine-wide on both; old 192.168.2.53 + WSD connections removed; LPOPV30 default = new printer (was the old one); memcare box default unchanged (iR-ADV). MedTech room in Memory Care. **TODO: GPO + domain accounts once joined.** |
| `\\CS-SERVER\Kitchen` | Canon MF743CDW | 192.168.3.232 (pre-migration) | (verify) | (kitchen) | chefs | — | Kitchen printer (with the chefs). Not yet migrated to VLAN20 this round. |
## Machine rename TODO
- **RECEPTIONIST-PC** (the Memory Care box, "memory care" user, S/N MJ0KQH4R, agent 57f19e17) shares its hostname with the front-desk RECEPTIONIST-PC box — too hard to tell apart in the agent list. **Rename STAGED 2026-06-30 -> `MEMCARE-STATION`; applies on next reboot** (not forced; user was active). The OTHER RECEPTIONIST-PC (frontdesk user, S/N MJ0KQHNP) is the actual front desk.
## Notes
- Workgroup machines (DESKTOP-MD6UQI3, CHEF-PC) get **direct-IP local printers** for now
(no domain auth / no point-and-print needed). Once domain-joined, switch them to the
GPO-deployed `\\CS-SERVER\<share>` model and map to the domain account.
- Detailed how-to + pfSense routing fix: `.claude/memory/project_cascades_vlan20_migration_routing.md`
and session log `clients/cascades-tucson/session-logs/2026-06/2026-06-30-howard-vlan20-printer-migration.md`.

View File

@@ -0,0 +1,68 @@
# Offboarding Record — Tamra Matthews
**Date:** 2026-06-30 · **Performed by:** Howard Enos (ClaudeTools session) · **Authorized by:** Howard Enos
**Separation type:** Voluntary (left Cascades, June 2026) · **Role:** Move-In Coordinator (Marketing / Sales)
**Runbook:** `docs/security/termination-procedures.md`
## Identities handled
- **M365 (cloud-only):** `tamra.matthews@cascadestucson.com` — id `2d9cf0d1-2b0b-424e-9cd1-91eaac408837`
(`onPremisesSyncEnabled=null` — cloud-mastered object, NOT Entra-synced)
- **On-prem AD:** `Tamra.Matthews` (was `OU=Marketing,OU=Departments,DC=cascades,DC=local` — separate
object, NOT Entra-synced; renamed from Tamra.Johnson 2026-04-13)
- **ALIS:** Not handled this session — Move-In Coordinator role; confirm/disable ALIS staff profile if
she had clinical/ALIS access (open follow-up below).
## Actions completed (M365)
| # | Action | Result |
|---|---|---|
| 1 | Revoke active sign-in sessions | HTTP 200 |
| 2 | Block sign-in (`accountEnabled=false`) | confirmed false |
| 3 | Reset password (random, vaulted) | OK — no elevation needed (holds no admin role, **no PAA stranding**) |
| 4 | Convert mailbox → **SharedMailbox** | confirmed (`RecipientTypeDetails=SharedMailbox`) |
| 5 | Grant **FullAccess** to Crystal Rodriguez, Megan Hiatt, Meredith Kuhn, Ashley Jensen | all 4 confirmed FullAccess |
| 6 | Hide from GAL (`HiddenFromAddressListsEnabled=true`) | confirmed |
| 7 | Remove **O365 Business Standard** license (`f245ecc8…`) | confirmed 0 licenses — **frees 1 seat** |
| 8 | Remove from groups `Sales`, `All Cascades`, `SG-SSPR-Eligible` | HTTP 204 ×3 |
### AutoMapping — all 4 auto-attach (resolved)
- **All four delegates** (Crystal Rodriguez, Ashley Jensen, Megan Hiatt, Meredith Kuhn) have
**FullAccess with AutoMapping** — the shared mailbox auto-attaches in their Outlook and stays
until they remove it.
- **Gotcha encountered + fix:** the first pass added all 4 in a rapid loop with `AutoMapping:$true`;
only Crystal + Ashley persisted — Megan + Meredith rolled back to NONE (cmdlet echoed success).
Cause: rapid sequential AutoMapping writes contend on the *same* `msExchDelegateListLink` attribute
on Tamra's mailbox; the middle writes lost the race and a failed link-write aborts the whole
`Add-MailboxPermission` transaction. **Fix:** re-grant the missing users **one at a time, spaced
(~6-8s), with verify-and-retry** — `Remove-MailboxPermission` → poll until NONE →
`Add-MailboxPermission -AutoMapping $true` → confirm it persists. Both took on the first spaced
attempt. (The literal `msExchDelegateListLink` list is not exposed in the Exchange Operator REST
schema; persistence of an `AutoMapping:$true` grant is the success signal.)
## Actions completed (on-prem AD, CS-SERVER)
- `Set-ADAccountPassword -Reset` (random, vaulted)
- `Disable-ADAccount Tamra.Matthews` → Enabled=False
- Group memberships: already 0 (no explicit groups) — nothing to strip
- `Move-ADObject``CN=Tamra Matthews,OU=Excluded-From-Sync,DC=cascades,DC=local`
## Retention / compliance
- **No Litigation Hold applied.** Decision (Howard, 2026-06-30): although Move-In Coordinator is a
resident-intake / PHI-adjacent role, Howard authorized the same posture as the Alma Montt
offboarding — **shared-mailbox conversion + zero-deletion** (no mailbox deleted), license removed to
free the seat. Mailbox is preserved under default MRM retention; revisit if her PHI-access
determination or a legal hold changes. Litigation Hold remains available later (tenant has Business
Premium / Exchange Plan 2) if the determination changes.
- Passwords stored for emergency recovery/audit only: vault `clients/cascades-tucson/tamra-matthews`
(`m365_password`, `ad_password`). **Do NOT re-enable without authorization.**
## Open follow-ups
- [ ] **ALIS staff profile** — confirm whether Tamra had ALIS access; if so, disable the staff record
(audit record stays). Her M365 SSO tie is already severed by the sign-in block.
- [x] ~~AutoMapping for Megan Hiatt + Meredith Kuhn~~**RESOLVED 2026-06-30**: re-granted one at a
time (spaced) so AutoMapping persisted. All 4 now auto-attach.
- [ ] **Reconcile** Tamra out of forward-looking plans/rosters. Share roster
`docs/migration/share-group-roster-proposed-2026-06-25.md` already shows her struck-through
*(leaving)*; `docs/servers/active-directory.md` OU=Marketing row updated to disabled +
Excluded-From-Sync. April/May questionnaires, CSVs, and the staff roster
`reports/cascades-staff-2026-04-22.csv` left as historical record.
- [ ] **Note (separate):** Megan Hiatt's M365 account carries a `CREDENTIAL_STUFFING_ACTIVE` flag in
the April tenant inventory — unrelated to this offboarding, but worth a breach check.

View File

@@ -75,7 +75,7 @@
|---------------|------|----------|-------|
| Megan.Hiatt | Megan Hiatt | Sales Director | M365: Sales@ |
| Crystal.Rodriguez | Crystal Rodriguez | Sales Associate | PC: CRYSTAL-PC. M365: Sales@ |
| Tamra.Matthews | Tamra Matthews | Move-In Coordinator | Renamed from Tamra.Johnson (2026-04-13) |
| ~~Tamra.Matthews~~ | ~~Tamra Matthews~~ | ~~Move-In Coordinator~~ | **OFFBOARDED 2026-06-30** — disabled, moved to `OU=Excluded-From-Sync`. See `docs/security/offboarding-2026-06-30-tamra-matthews.md` |
**OU=Resident Services**
| SamAccountName | Name | Position | Notes |

View File

@@ -0,0 +1,53 @@
# Breach Re-Check — megan.hiatt@cascadestucson.com
**Date:** 2026-06-30 · **Performed by:** Howard Enos (ClaudeTools session)
**Tenant:** Cascades of Tucson (cascadestucson.com, `207fa277-e9d8-4eb7-ada1-1064d2221498`)
**Object ID:** `ab306d53-6d6c-4f8f-a982-f4f571722178`
**Why:** Megan's account carried a `CREDENTIAL_STUFFING_ACTIVE` marker in the April tenant
inventory. This re-check verifies whether the April remediation held and whether the campaign is
still active. Read-only; no actions taken.
## Verdict — CLEAN. April remediation held; attack no longer active.
The April credential-stuffing campaign (119 malicious sign-in attempts over 30 days from 7
EU/UK IPs, all blocked at error 50053) has **ceased**, and the hardening applied in April is
**still in place**. No compromise indicators.
## April remediation — current status (did it hold?)
| April control | Current state (2026-06-30) | Held? |
|---|---|---|
| Disable SMTP AUTH on Megan's mailbox | `SmtpClientAuthenticationDisabled=true` | **Yes** |
| Disable IMAP | `ImapEnabled=false` | **Yes** |
| Disable POP | `PopEnabled=false` | **Yes** |
| Rotate password | Last change `2026-05-28` (post-April; rotated) | **Yes** |
| MFA = Authenticator (not SMS) | Methods: password + microsoftAuthenticator only; **no SMS**, no new method | **Yes** |
| Tenant anti-spam / anti-phish hardening (SPF hard-fail, mailbox-intelligence quarantine, first-contact tips) | Applied tenant-wide in April (Default policies) | (tenant-level, unchanged) |
EWS / ActiveSync / OWA / MAPI remain enabled — same as April; those are modern-auth capable, not
basic-auth bypass paths.
## Live breach check (10-point) — all clean
| # | Check | Result |
|---|---|---|
| Sign-ins (30d) | **0 interactive, 0 non-US** (was 119 malicious + 16 US-success in April) | No active attack; no foreign success ever |
| Account | `accountEnabled=true`, cloud-only | normal |
| Auth methods | password + Microsoft Authenticator (2) | no new/weak method |
| Inbox rules | 1 visible + 4 hidden — all benign (Junk default, 2 OOF system, user "Cascade of Tucson" move rule) | no forward/redirect/delete |
| Mailbox permissions | 0 non-SELF | no delegates |
| SendAs | 0 non-SELF | none |
| Forwarding | `ForwardingAddress=null`, `ForwardingSmtpAddress=null` | not forwarding |
| OAuth grants | 5 — Outlook Mobile ×2, third-party OIDC SSO, Contacts.Read (April set) **+ ALIS SSO SP `e1cae4ad…` User.Read** (expected, June 3 ALIS rollout) | benign |
| Directory audits (30d) | 0 | no admin tampering |
| Risk detections | 0 (risky-user read still `Forbidden` — known `IdentityRiskyUser.Read.All` consent gap, not a finding) | — |
## Notes
- **`CREDENTIAL_STUFFING_ACTIVE` is a stale April marker**, not a live signal — the campaign is no
longer hitting (0 attempts in 30d). It reflects April state captured in the tenant inventory.
- The only April recommendation not confirmed implemented is **C1 — Conditional Access US-only
geo-block** for office users. It is now **optional/low-urgency**: every stuffing attempt was
already blocked by MFA + MS IP-reputation, and the campaign has stopped. Worth scheduling as
baseline hardening but not an active risk.
- Raw artifacts: `/tmp/remediation-tool/207fa277-…/user-breach/megan_hiatt_cascadestucson_com/`.

View File

@@ -0,0 +1,135 @@
## User
- **User:** Howard Enos (howard)
- **Machine:** Howard-Home
- **Role:** tech
## Session Summary
Offboarded **Tamra Matthews** (Move-In Coordinator, Marketing/Sales) from Cascades of Tucson
after she left the facility in June 2026. Followed the canonical termination runbook
(`docs/security/termination-procedures.md`) and the Alma Montt offboarding (2026-06-25) as the
proven pattern. Work spanned the M365 cloud tenant (via the `remediation-tool` skill) and the
on-prem AD domain controller CS-SERVER (via the `rmm` skill); both passwords were vaulted.
Established live pre-state first: Tamra's M365 object (`tamra.matthews@cascadestucson.com`,
id `2d9cf0d1-2b0b-424e-9cd1-91eaac408837`) is **cloud-only** (`onPremisesSyncEnabled=null`) with a
single O365 Business Standard license and membership in `Sales`, `All Cascades`, and
`SG-SSPR-Eligible`. The on-prem `Tamra.Matthews` is a **separate, non-synced** object in
`OU=Marketing,OU=Departments` with no explicit group memberships. All four mailbox-delegate
recipients (Crystal Rodriguez, Megan Hiatt, Meredith Kuhn, Ashley Jensen) resolved as
UserMailboxes; all three target groups were static (not dynamic), so removable.
Before mutating anything, surfaced one genuine compliance fork to Howard: unlike Alma (no PHI),
Move-In Coordinator is a resident-intake / PHI-adjacent role, so the runbook's 7-yr Litigation
Hold could apply. Howard authorized the **Alma-style posture** — shared-mailbox + zero-deletion,
free the seat, **no litigation hold** (revisit if the PHI determination changes; hold remains
available since the tenant has Business Premium/Exchange Plan 2).
Executed the M365 sequence (revoke sessions, block sign-in, vaulted password reset, convert to
SharedMailbox, grant the 4 delegates FullAccess+AutoMapping, hide from GAL, remove license, strip
3 groups), then the on-prem AD lockdown (reset password, Disable-ADAccount, move to
`OU=Excluded-From-Sync`). Verified every step against live state. Vaulted both passwords, wrote the
offboarding record, reconciled the AD current-state doc + share roster, and synced. Per Howard's
direction, AutoMapping was then fixed for all 4 delegates and a `/save` run before proceeding to a
breach check on Megan Hiatt.
## Key Decisions
- **No litigation hold despite PHI-adjacent role** — Howard explicitly authorized the same
preserve-but-no-hold posture as Alma. Documented the deviation in the offboarding record so the
PHI-role/no-hold decision is auditable.
- **Treated the M365 object as cloud-only and the AD object as separate** — `onPremisesSyncEnabled=null`
confirmed the M365 account is cloud-mastered; the domain lockdown was a distinct operation on
CS-SERVER (same split as Alma).
- **Removed license only AFTER shared-mailbox conversion** — per runbook, so the mailbox is never a
licensed-then-unlicensed user mailbox at risk of default-retention deletion.
- **Fixed AutoMapping by spaced, one-at-a-time re-grants** rather than leaving Megan/Meredith on
manual-add — Howard wanted the box to auto-attach and stay.
## Problems Encountered
- **AutoMapping silently rolled back for 2 of 4 delegates.** The first pass added all 4 in a rapid
loop with `AutoMapping:$true`; the cmdlet echoed `[FullAccess]` for all 4, but a readback showed
only Crystal + Ashley persisted — Megan + Meredith were NONE. Cause: rapid sequential AutoMapping
writes contend on the same `msExchDelegateListLink` multivalued attribute on Tamra's mailbox; a
failed link-write aborts the whole `Add-MailboxPermission` transaction, so the middle writes lost
the race and rolled back entirely. **Resolved** by re-granting one user at a time, spaced ~6-8s,
with `Remove-MailboxPermission` → poll-until-NONE → `Add-MailboxPermission -AutoMapping $true`
verify-persists. Both took on the first spaced attempt. Logged to `errorlog.md` (--friction).
- **Graph read-replica lag** — immediately after `PATCH accountEnabled=false` (HTTP 204), a verify
read still showed `accountEnabled=true`; a re-read seconds later showed false. Not a failure, just
eventual consistency. Same lag bit the Meredith remove (still showed FullAccess right after the
remove), handled with a poll-until-NONE loop.
- **msExchDelegateListLink not readable via REST** — the Exchange Operator REST `Get-Mailbox` schema
doesn't expose the attribute, so AutoMapping can't be directly read; persistence of an
`AutoMapping:$true` grant (no rollback) is the success signal used instead.
## Configuration Changes
- **Created:** `clients/cascades-tucson/docs/security/offboarding-2026-06-30-tamra-matthews.md`
(offboarding record).
- **Created:** `clients/cascades-tucson/session-logs/2026-06/2026-06-30-howard-tamra-matthews-offboarding.md`
(this log).
- **Created (vault):** `clients/cascades-tucson/tamra-matthews.sops.yaml` (encrypted; m365_password +
ad_password + metadata). Committed + pushed to the vault repo.
- **Edited:** `clients/cascades-tucson/docs/servers/active-directory.md` — OU=Marketing Tamra.Matthews
row struck + annotated OFFBOARDED/disabled/Excluded-From-Sync.
- **Edited:** `clients/cascades-tucson/docs/migration/share-group-roster-proposed-2026-06-25.md`
Tamra `(leaving)``(OFFBOARDED 2026-06-30)` (4 lines).
- **Appended:** `errorlog.md` — EXO AutoMapping rollback friction entry.
## Credentials & Secrets
- **Tamra Matthews offboarding passwords** (emergency/audit only; **DO NOT re-enable without
authorization**): vault `clients/cascades-tucson/tamra-matthews` — fields `m365_password`,
`ad_password`. Generated random, complexity-guaranteed; not pasted into chat/tickets. Scratchpad
plaintext was scrubbed after vaulting.
## Infrastructure & Servers
- **M365 tenant:** cascadestucson.com — Tenant ID `207fa277-e9d8-4eb7-ada1-1064d2221498`
- **Tamra M365 object id:** `2d9cf0d1-2b0b-424e-9cd1-91eaac408837` (cloud-only)
- **Removed license SKU:** `f245ecc8-75af-4f8e-b61f-27d8114de5f3` (O365 Business Standard) — seat freed
- **Delegate mailbox GUIDs:** megan.hiatt `448588b1-cb16-41e4-95b3-a496ebf0c7e8`; meredith.kuhn
`02ebe159-818e-4814-a72a-3620dea944a0`
- **Groups removed from:** `Sales` `757e7628-ff38-477c-a5a1-71b27e94d365` (Unified),
`All Cascades` `0344d8ae-bf3c-4b2f-b30b-c9fa93a20aa2` (Unified),
`SG-SSPR-Eligible` `d6044864-a0ef-4c30-ba37-cdba7074437e` (security)
- **On-prem DC:** CS-SERVER (192.168.2.254), `cascades.local`; GuruRMM agent id (live this session)
`c39f1de7-d5b6-45ae-b132-e06977ab1713`. Tamra final DN
`CN=Tamra Matthews,OU=Excluded-From-Sync,DC=cascades,DC=local`, Enabled=False.
- **Remediation apps used:** Security Investigator (`bfbc12a4`, Graph+EXO read), Exchange Operator
(`b43e7342`, EXO write), User Manager (`64fac46b`, Graph user/group/license write), Tenant Admin
(`709e6eed`, password reset — no PAA elevation needed for a non-admin target).
## Commands & Outputs
- Block sign-in: `PATCH /users/{id}` `{"accountEnabled":false}` → HTTP 204 (verify lagged true→false).
- Revoke sessions: `POST /users/{id}/revokeSignInSessions` → HTTP 200.
- Password reset: `reset-password.sh … tamra.matthews …``[OK] no elevation needed` (non-admin).
- Convert shared: EXO `Set-Mailbox -Type Shared``RecipientTypeDetails=SharedMailbox`.
- Grants (final): all 4 `Get-MailboxPermission -User <u>``["FullAccess"]`.
- License remove: `POST /users/{id}/assignLicense` removeLicenses=[f245ecc8…] → 0 licenses.
- Group removes: `DELETE /groups/{gid}/members/{id}/$ref` → 204 ×3.
- AD lockdown (RMM cmd `a788a445…`, exit 0): `Set-ADAccountPassword -Reset` + `Disable-ADAccount` +
`Move-ADObject``Enabled=False`, DN in `OU=Excluded-From-Sync`, Groups=0.
- AutoMapping fix: per-user `Remove-MailboxPermission` → poll NONE → `Add-MailboxPermission -AutoMapping $true`
→ persists (Megan + Meredith, first spaced attempt).
## Pending / Incomplete Tasks
- **ALIS** — Howard handling; unsure Tamra used ALIS. If she had a staff profile, disable it
(M365 SSO tie already severed by the sign-in block).
- **Breach check on Megan Hiatt** — NEXT step this session. Megan's account carried a
`CREDENTIAL_STUFFING_ACTIVE` marker in the April tenant inventory; Howard recalls an April
remediation that should have stopped it — verify it held (`/remediation-tool check megan.hiatt@…`).
- **Litigation hold** — not applied (Howard authorized); revisit only if Tamra's PHI-access
determination or a legal hold changes.
## Reference Information
- Offboarding record: `clients/cascades-tucson/docs/security/offboarding-2026-06-30-tamra-matthews.md`
- Termination runbook: `docs/security/termination-procedures.md`
- Prior offboarding (pattern): `docs/security/offboarding-2026-06-25-alma-montt.md`
- Vault: `clients/cascades-tucson/tamra-matthews`
- Cascades wiki: `wiki/clients/cascades-tucson.md`

View File

@@ -0,0 +1,116 @@
## User
- **User:** Howard Enos (howard)
- **Machine:** Howard-Home
- **Role:** tech
## Session Summary
Migrated the front-desk Epson ET-5800 and the Life Enrichment Canon MF741CDW onto the new Staff VLAN 20 (10.0.20.0/24 / "CSCNET"), as part of the ongoing move of staff machines + printers off the flat old LAN ("CSC ENT", 192.168.0.0/22). All work driven via GuruRMM (CS-SERVER + the client agents) plus one pfSense GUI change.
First, the front-desk ET-5800: confirmed RECEPTIONIST-PC is two physical boxes (frontdesk = serial MJ0KQHNP at 10.0.20.102; the other is Memory Care reception). Repointed the CS-SERVER `FrontDesk` share from `TCP_192.168.2.147` to `TCP_10.0.20.221` (printer set to static .221 by Howard), removed the old port, removed the stale local `ET-5800 Series(Network)` printer from the frontdesk box, mapped `\\CS-SERVER\FrontDesk` and set it default. Test page printed.
Hit a hard blocker: CS-SERVER could not reach ANY VLAN 20 printer (.221/.220/.94/.78:9100) even though it pinged the VLAN20 gateway 10.0.20.1. Root cause was not a firewall block — the LAN "Default allow LAN to any" rule has Gateway = WAN_Group (dual-WAN policy routing), shoving LAN->internal-VLAN traffic out the WAN. Fixed with one pass rule at the top of the pfSense LAN interface (source CS-SERVER 192.168.2.248, dest 10.0.20.0/24, gateway = default). This also un-broke the already-migrated Business Office/Life Enrichment/MC Reception shares. (pfSense SSH from the VPN is blocked, so the unifi-wifi pfsense-ssh.sh skill returned empty; did the rule in the GUI.)
Then Life Enrichment (room 132, users sharon.edwards @ DESKTOP-DLTAGOI and susan.hicks @ DESKTOP-ROK7VNM). The old per-user mapping `\\CS-SERVER\1F-132-RecRoom-Canon` was orphaned (share renamed to `LifeEnrichment` on the server). Added `\\CS-SERVER\LifeEnrichment` for both users (defaults left as `Copy Room` per Howard). Mapping initially failed with the PrintNightmare elevation prompt (0x800702e4) and the per-machine `/ga` path silently failed at logon (PrintService event 513 / error 0xBCB) — both are the default `RestrictDriverInstallationToAdministrators` blocking the standard user from pulling the driver. Resolved by setting the Point-and-Print policy (scoped to CS-SERVER) on both machines, after which the user-session add was promptless+immediate.
Final blocker: jobs spooled but nothing printed; the Canon panel showed Error #822. Diagnosis: the rebuilt `LifeEnrichment` share used the wrong PDL — `Canon Generic Plus PCL6` — but the MF741 is UFR II only (can't parse PCL). CS-SERVER only had PCL6/PS3/XPS staged. Pulled the `Canon Generic Plus UFR II V250` driver from a client's DriverStore to CS-SERVER (using the vaulted sysadmin domain-admin cred), installed it, and switched the share to it. Test prints from the server, Susan's machine, and Sharon's machine all printed (Howard confirmed at the printer). Both LE machines verified on the UFR II driver, defaults unchanged.
## Key Decisions
- **pfSense fix = policy-route bypass, not an allow rule.** The traffic was never blocked; it was misrouted out the WAN by the LAN catch-all's WAN_Group gateway. Added a top LAN pass rule with gateway=default scoped to CS-SERVER's source IP, so residents (per-unit /28 VLANs) and guests (VLAN 50) can't match it (different ingress interface + different source). Did it in the GUI because pfSense SSH/22 is blocked from the OpenVPN subnet.
- **Point-and-Print policy is the correct "apply our admin rights" fix**, not making end users local admins and not a security bypass. Scoped silent driver install to CS-SERVER only. This is the prerequisite a printer-deployment GPO needs; without it a GPO-pushed printer fails the same 0xBCB way. The caregiver machines already have this (why their printer GPO works).
- **Server-share model kept** (Howard's preference) rather than falling back to direct-IP printers, even when the UFR II driver wasn't on the server — pulled the driver across with the domain-admin cred instead.
- **Driver transfer direction = client -> server.** CS-SERVER (192.168.2.x) cannot reach a client's C$ (client host-firewall scopes File/Print sharing to LocalSubnet; CS-SERVER is off-subnet). The client pushes to `\\CS-SERVER\C$` instead.
- **Defaults left untouched** on the LE users per explicit instruction (they keep `Copy Room`).
## Problems Encountered
- **CS-SERVER could not reach VLAN 20 printers** -> LAN "allow LAN to any" rule policy-routed via WAN_Group. Fixed with top LAN pass rule, gateway=default, src CS-SERVER, dst 10.0.20.0/24.
- **pfSense SSH from VPN timed out** (tcp/22 dropped, GUI 443 open) -> the unifi-wifi pfsense-ssh.sh skill silently returned empty (sends ssh stderr to /dev/null). Worked around via the pfSense GUI.
- **Printer mapping elevation prompt (0x800702e4)** for standard users, and per-machine `/ga` silently failing at logon (event 513 / 0xBCB) -> set Point-and-Print policy (RestrictDriverInstallationToAdministrators=0 + trusted CS-SERVER) -> promptless.
- **LE Canon: spooled but nothing printed, Error #822** -> wrong driver (PCL6) on an UFR-II-only device -> installed Canon Generic Plus UFR II V250 on CS-SERVER and switched the share.
- **Stale cached driver on clients** after the server driver swap -> refreshed each client connection (Remove + AddWindowsPrinterConnection) so it dropped PCL6 and pulled UFR II.
- **Backslash mangling** in RMM PowerShell payloads (literal `\\` -> single `\` through jq/agent) -> build UNC with `[char]92`. Logged to errorlog as friction.
## Configuration Changes
- pfSense (Cascades, 192.168.0.1): added LAN firewall rule (top) — Pass, IPv4, proto Any, Source 192.168.2.248, Dest 10.0.20.0/24, Gateway = default. Description "CS-SERVER to VLAN20 (full server access, bypass WAN policy-route)".
- CS-SERVER `FrontDesk` share: port `TCP_192.168.2.147` -> `TCP_10.0.20.221`; old port removed; ShareName `FrontDesk` unchanged.
- CS-SERVER `Life Enrichment - Canon MF741CDW` share (`LifeEnrichment`): driver `Canon Generic Plus PCL6` -> `Canon Generic Plus UFR II V250` (port TCP_10.0.20.94 unchanged). Installed UFR II driver package (now `oem15.inf`); staging files left at `C:\Temp\ufr2drv` on CS-SERVER (can be deleted).
- DESKTOP-ROK7VNM (susan.hicks) + DESKTOP-DLTAGOI (sharon.edwards): set Point-and-Print policy (HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Printers): `RestrictDriverInstallationToAdministrators=0`; subkey `PointAndPrint`: `Restricted=1, TrustedServers=1, ServerList=CS-SERVER, InForest=0, NoWarningNoElevationOnInstall=1, UpdatePromptSettings=2`. Added `\\CS-SERVER\LifeEnrichment` (UFR II), removed orphaned `1F-132-RecRoom-Canon`. Defaults unchanged.
- RECEPTIONIST-PC (frontdesk box, MJ0KQHNP): removed local `ET-5800 Series(Network)`; mapped `\\CS-SERVER\FrontDesk`, set default.
- Memory: updated `.claude/memory/project_cascades_vlan20_migration_routing.md` (+ MEMORY.md index line). Errorlog: 2 friction entries (UNC backslash, rmm printer elevation).
## Credentials & Secrets
- Used the vaulted CS-SERVER admin: `clients/cascades-tucson/cs-server.sops.yaml` (username `sysadmin`, domain admin on cascades.local) — for the cross-machine driver pull. No new credentials created or discovered. Not exposed here (already vaulted).
## Infrastructure & Servers
- CS-SERVER 192.168.2.254 / 192.168.2.248 (DC, DNS, File + Print server), GuruRMM agent `c39f1de7-d5b6-45ae-b132-e06977ab1713`. Routes to VLAN20 from .248.
- pfSense 192.168.0.1 (Plus 25.07). LAN = 192.168.0.0/22. Dual-WAN (WAN_Group). VLAN 20 (Staff/Internal) 10.0.20.0/24 gw 10.0.20.1. SSH/22 blocked from OpenVPN subnet (GUI 443 open).
- Printers (VLAN 20, static): Front Desk Epson ET-5800 = 10.0.20.221 (RAW 9100); Life Enrichment Canon MF741CDW = 10.0.20.94 (RAW 9100, UFR II); Business Office Brother = 10.0.20.220 (was powered off this session); MC Reception Epson ET-5800 = 10.0.20.78; Life Enrichment also reachable .94.
- Agents: DESKTOP-ROK7VNM (susan.hicks) `4832ff97-196d-4de5-a3b9-dadf9adb2c7a`; DESKTOP-DLTAGOI (sharon.edwards) `4bdf92f6-7a84-4b71-81df-75d59febf39d`; RECEPTIONIST-PC frontdesk box `2e8d8b73-82f6-4151-a3ce-879c55de4b82`; MemCare reception box `57f19e17-8792-46cc-b9fd-f1909836cd17`.
## GPO Reference (for the printer-GPO work Howard flagged)
Existing GPOs on cascades.local (from CS-SERVER `Get-GPO -All`):
`CSC - Always Wait For Network`, `CSC - Caregiver Device Lockdown`, `CSC - Caregiver Workstation`, `CSC - Drive Mappings`, `CSC - Folder Redirection`, `CSC - Folder Redirection (LE)`, **`CSC - Life Enrichment Printers`**, **`CSC - Printer Deployment`**, `CSC - Reception Workstation Policy`, `CSC - Security Baseline`, `CSC - Windows Update`, `Power Options`, + the two Defaults.
For the printer GPO to work promptlessly, it needs TWO layers:
1. **Point-and-Print policy (computer GPO, fleet-wide)** = the exact registry values set manually this session (see Configuration Changes). Caregiver machines already have it; staff/LE machines did not. Put this in a computer GPO so every staff machine can silently install CS-SERVER printers.
2. **Printer deployment** = GPP Printers item / Deployed Printers mapping `\\CS-SERVER\<share>` to the right users/OU/room. `CSC - Life Enrichment Printers` likely still references the OLD share name (`1F-132-RecRoom-Canon`) — repoint it to `\\CS-SERVER\LifeEnrichment`. NOTE: `CSC - Printer Deployment` is the known disabled/empty/reference-only one.
Per-user/room printer map confirmed this session (extend as machines migrate):
- Front desk (RECEPTIONIST-PC frontdesk box) -> `\\CS-SERVER\FrontDesk` (Epson ET-5800, default).
- Life Enrichment room 132 -> `\\CS-SERVER\LifeEnrichment` (Canon MF741CDW, **UFR II driver**) for sharon.edwards + susan.hicks (NOT default; their default stays Copy Room).
CRITICAL driver note for any GPO deploying the LE Canon: it MUST use **Canon Generic Plus UFR II V250** (INF cnlb0ma64.inf), NOT PCL6 — PCL6 produces Error #822 (nothing prints).
## Commands & Outputs
- pfSense verify (RMM, CS-SERVER): `10.0.20.221:9100=True`, `.94=True`, `.78=True`, `.220=False` (powered off). VLAN20->CS-SERVER 445 = True.
- Error #822 confirmation: raw PCL to 10.0.20.94:9100 -> Error 822 (printer can't parse PCL). `Get-PrinterDriver` on CS-SERVER had only PCL6/PS3/XPS Canon; client had `Canon Generic Plus UFR II V250` (InfPath cnlb0ma64.inf).
- Driver install: client pushed package to `\\CS-SERVER\C$\Temp\ufr2drv` (159 files); `pnputil /add-driver cnlb0ma64.inf /install` -> oem15.inf; `Add-PrinterDriver -Name "Canon Generic Plus UFR II V250"`; `Set-Printer -DriverName`.
- PrintService event 513 / error 0xBCB on DESKTOP-ROK7VNM = per-machine `/ga` failing to install driver for the standard user (pre Point-and-Print fix).
## Pending / Incomplete Tasks
- **Printer GPO (Howard's next focus):** put the Point-and-Print policy into a computer GPO fleet-wide; repoint `CSC - Life Enrichment Printers` to `\\CS-SERVER\LifeEnrichment` (UFR II); build out per-room printer-deployment items as the who-needs-what map firms up.
- **Business Office printer (10.0.20.220)** was powered off / unreachable this session — verify it when onsite.
- **Cascades printer skill (Howard's idea):** package this migration's how-to (VLAN routing/pfSense bypass, server-share repoint, Point-and-Print policy, UFR II driver, [char]92 UNC) into a reusable skill so future printer adds are one call.
- Optional cleanup: delete `C:\Temp\ufr2drv` on CS-SERVER (driver staging files).
- pfSense SSH-from-VPN still blocked (separate; only needed to use the pfsense-ssh.sh skill remotely).
## Reference Information
- GuruRMM API: http://172.16.3.30:3001 (vault infrastructure/gururmm-server.sops.yaml).
- Memory: `.claude/memory/project_cascades_vlan20_migration_routing.md`.
- UFR II driver: `Canon Generic Plus UFR II V250`, INF `cnlb0ma64.inf`, client DriverStore path `C:\Windows\System32\DriverStore\FileRepository\cnlb0ma64.inf_amd64_d4f4062dad259878`.
- Point-and-Print policy key: `HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Printers` (+ `\PointAndPrint`).
## Update: 12:44 PT — more VLAN20 printers (dining/chef/medtech), workgroup machines, machine rename, GPO planning doc
Continued the VLAN 20 printer migration with several **workgroup** (not-domain-joined) machines, where the clean approach is a **direct-IP local printer installed as SYSTEM (machine-wide / all users)** — no `\\CS-SERVER` share, no domain auth, no point-and-print prompt.
- **Dining Room Manager** (DESKTOP-MD6UQI3, WORKGROUP, user `dining manager` / Alyssa): set up direct-IP `Dining Room Manager - Canon MF743CDW` -> 10.0.20.228 (UFR II driver `Canon Generic Plus UFR II V250`, already present), machine-wide, default. Removed stale `Kitchen Admin` USB printer (per Howard). Initially misnamed it "Kitchen -" -> renamed to "Dining Room Manager -" (Howard: the kitchen printer is a separate device with the chefs; this is her own-room printer).
- **Chef's Office** (CHEF-PC, WORKGROUP): set up direct-IP `Chef Office - Brother MFC-9330CDW` -> 10.0.20.236 (driver `Brother MFC-9330CDW Printer`), machine-wide / all users (Howard: machine still needs to be domain-joined). LEFT the existing USB `Chef Printer` in place and LEFT it as the chef's default — verified per-user defaults via registry: real user `JD Martin` still defaults to USB `Chef Printer` (the "default = Chef Office" seen post-install was only SYSTEM's context, not a user). So JD Martin = chef on CHEF-PC.
- **Memory Care front desk** (MEMRECEPT-PC, WORKGROUP, user `memfrtdesk`): identified + marked in the GPO doc. Printer = `MCReception` Epson ET-5800 @ 10.0.20.78. Currently only has the Epson via OLD vendor/WSD ports (`EP833571:ET-5800 SERIES`), not the static .78. NOT set up yet (Howard asked to mark it down for the GPO; setup TBD).
- **Memory Care MedTech Brother MFC-L8900CDW @ 10.0.20.74** set up direct-IP machine-wide on BOTH the memcare box and DESKTOP-LPOPV30 (user `karen rossini`); removed the OLD connections on the retired IP 192.168.2.53 (+ a stale WSD `Med Tech` on the memcare box). On LPOPV30 the old one was Karen's default -> set the NEW printer as her default. Memcare box default left as iR-ADV.
- **Machine rename:** RECEPTIONIST-PC (the Memory Care box, "memory care" user, S/N MJ0KQH4R, agent 57f19e17) shares its hostname with the front-desk RECEPTIONIST-PC box and was hard to tell apart -> `Rename-Computer -NewName MEMCARE-STATION -Force` STAGED (applies on next reboot; not forced, user active). The OTHER RECEPTIONIST-PC (frontdesk user, S/N MJ0KQHNP) is the real front desk.
- **GPO planning doc created:** `clients/cascades-tucson/docs/printer-gpo-map.md` — running printer->machine->user->IP->driver map for the eventual printer GPO, including the required Point-and-Print policy layer, the per-room/per-user assignments, the UFR II driver requirement for Canon MF741/743, and TODOs (add to GPO + map to domain accounts once the workgroup machines are domain-joined; repoint `CSC - Life Enrichment Printers` GPO to the new share).
**Decisions/notes this update:**
- Workgroup machines get direct-IP printers now; switch to GPO-deployed `\\CS-SERVER\<share>` once domain-joined.
- A SYSTEM-context `Get-CimInstance Win32_Printer .Default` reports SYSTEM's default, NOT the logged-on user's — read per-user defaults from `HKU\<sid>\...\Windows\Device` to see the real user default.
- Building the direct-IP printers used `Add-PrinterPort`/`Add-Printer` (SYSTEM) so they're machine-wide; per-user default changes done via `WScript.Network.SetDefaultPrinter` in the user session.
**Problem:** on the memcare box the spooler went unreachable (`0x800706ba`) right at the test-print step after add+remove; recovered with `Restart-Service Spooler -Force`, re-verified the new printer (Normal) and re-sent the test.
**Pending after this update:**
- Reboot MEMCARE-STATION (memcare box) when convenient to apply the rename.
- Set up the Memory Care front-desk Epson ET-5800 (10.0.20.78) on MEMRECEPT-PC if desired (currently only marked down).
- Confirm dining/chef/medtech test pages printed (Howard verifying at the printers).
- All workgroup machines (DESKTOP-MD6UQI3, CHEF-PC, MEMCARE-STATION, MEMRECEPT-PC, DESKTOP-LPOPV30): domain-join + GPO migration still pending.
New IPs/printers this update: Dining Canon MF743CDW 10.0.20.228; Chef Brother MFC-9330CDW 10.0.20.236; MedTech Brother MFC-L8900CDW 10.0.20.74; MemCare front desk Epson ET-5800 10.0.20.78 (not yet set up).