From 68153cf9b6adc7f87ce7cbd335d4d2d9898f323b Mon Sep 17 00:00:00 2001 From: Howard Enos Date: Fri, 17 Apr 2026 23:51:20 -0700 Subject: [PATCH] sync: auto-sync from ACG-TECH03L at 2026-04-17 23:51:18 Author: Howard Enos Machine: ACG-TECH03L Timestamp: 2026-04-17 23:51:18 --- WORKITEMS.md | 8 +- clients/cascades-tucson/CONTEXT.md | 65 ++++++ .../scripts/fix-live-shellfolders.ps1 | 64 ++++++ .../scripts/hive-cleanup-shellfolders.ps1 | 102 +++++++++ ...cades-onboarding-and-folder-redirection.md | 196 ++++++++++++++++++ 5 files changed, 434 insertions(+), 1 deletion(-) create mode 100644 clients/cascades-tucson/CONTEXT.md create mode 100644 clients/cascades-tucson/scripts/fix-live-shellfolders.ps1 create mode 100644 clients/cascades-tucson/scripts/hive-cleanup-shellfolders.ps1 create mode 100644 clients/cascades-tucson/session-logs/2026-04-17-howard-cascades-onboarding-and-folder-redirection.md diff --git a/WORKITEMS.md b/WORKITEMS.md index b0a93c1..5ff8d17 100644 --- a/WORKITEMS.md +++ b/WORKITEMS.md @@ -9,7 +9,13 @@ Tag yourself to claim. Check off when done. Add new items at the bottom of the r ## Active - [ ] Deploy session manager to SAGE-SQL (IIS app, Windows Auth) — files ready at `clients/dataforth/session-manager/` — @mike | added 2026-04-17 -- [ ] Cascades Synology (cascadesds) — get admin creds, add to vault — @howard | added 2026-04-17 +- [x] Cascades Synology (cascadesds) — get admin creds, add to vault — @howard | done 2026-04-17 (vault: `clients/cascades-tucson/synology-cascadesds.sops.yaml`) +- [ ] Cascades — second Life Enrichment machine: end-to-end folder redirection test (tomorrow). See `clients/cascades-tucson/session-logs/2026-04-17-howard-cascades-onboarding-and-folder-redirection.md` — @howard | added 2026-04-17 +- [ ] Cascades GPO — add Desktop/Pictures/Music/Videos/Favorites once 2nd machine validates the pattern, and retire the DLTAGOI Desktop reg hack — @howard | added 2026-04-17 +- [ ] Cascades — build matching folder-redirection GPOs for every other department (Nursing, Admin, Maintenance, etc.) once Life Enrichment is proven — @howard | added 2026-04-17 +- [ ] Cascades — design OneDrive-to-server migration plan (machines with Documents/Desktop already in OneDrive KFM need data-migration + unlink BEFORE the GPO applies) — @unassigned | added 2026-04-17 +- [ ] Cascades HIPAA hardening — `Set-SmbShare -Name homes -EncryptData $true`, enable file-access auditing on D:\Homes, verify BitLocker on CS-SERVER D: — @unassigned | added 2026-04-17 +- [ ] GuruRMM bug — agent command executor can wedge after a user-context PS command hangs; doesn't recover on reboot. File + fix. — @mike | added 2026-04-17 - [ ] Howard Gitea account — create via web UI at git.azcomputerguru.com — @mike | added 2026-04-16 - [ ] desertrat.com — add DMARC p=reject + harden SPF on Route 53 (need AWS access) — @unassigned | added 2026-04-17 - [ ] desertrat.com — long-term migration from WebSvr to IX + MailProtector — @unassigned | added 2026-04-17 diff --git a/clients/cascades-tucson/CONTEXT.md b/clients/cascades-tucson/CONTEXT.md new file mode 100644 index 0000000..899ec86 --- /dev/null +++ b/clients/cascades-tucson/CONTEXT.md @@ -0,0 +1,65 @@ +# Cascades of Tucson — Client Context + +**Last updated:** 2026-04-17 (Howard) + +## Identity + +- Business: Cascades of Tucson (senior living community) +- Syncro customer ID: **20149445** +- Primary contact: Meredith Kuhn — meredith.kuhn@cascadestucson.com — (520) 886-3171 +- Location: 201 N Jessica Ave, Tucson AZ 85710 + +Full contact list + Wi-Fi, KPAX, M365 admin, UniFi hardware MACs, GoDaddy are in the Syncro customer notes field for 20149445. + +## Infrastructure + +| Resource | Address | Vault path | +|---|---|---| +| pfSense firewall | 192.168.0.1 | `clients/cascades-tucson/pfsense-firewall.sops.yaml` | +| Synology NAS `cascadesds` | 192.168.0.120:5000 (DSM) | `clients/cascades-tucson/synology-cascadesds.sops.yaml` | +| CS-SERVER (DC + file server) | reachable at 192.168.2.254 from the Wi-Fi-2 subnet on DLTAGOI; domain `cascades.local` | `clients/cascades-tucson/cs-server.sops.yaml` | +| `svc-audit-upload` | service account for Syncro audit upload to `AuditDrop$` share | `clients/cascades-tucson/svc-audit-upload.sops.yaml` | +| `\\CS-SERVER\homes` | file share at `D:\Homes`; per-user subfolders for folder redirection. Domain Users: Change. Domain Admins: Full. **EncryptData currently false — HIPAA workitem to flip on.** | — | + +## GuruRMM + +- Client: **Cascades of Tucson** (code `CASC`, id `42e1b0e3-f8b7-4fc5-86bd-06bdbb073b7f`) +- Site: **CascadesTucson** (code `GOLD-MOON-4620`, id `c157c399-82d3-4581-979a-b9fad70f4fef`) +- Agent enrollment key: encrypted at `clients/cascades-tucson/gururmm-site-main.sops.yaml` (shown once by the API; do not regenerate unless compromised — agents using the current key keep working on regeneration only if the server rotates atomically) + +### Agents currently enrolled + +| Hostname | Role | Agent ID | +|---|---|---| +| DESKTOP-DLTAGOI | Life Enrichment test workstation (Sharon Edwards) | `0ed72c1c-40c7-4bd4-afed-e0bcb198936f` | +| CS-SERVER | Domain controller / file server | `6766e973-e703-47c1-be56-76950290f87c` | + +### Agent deployment (ScreenConnect) + +```powershell +$u='https://rmm-api.azcomputerguru.com/downloads/gururmm-agent-windows-amd64-latest.exe'; +$d='C:\Windows\Temp\gururmm-agent.exe'; +Invoke-WebRequest $u -UseBasicParsing -OutFile $d; +& $d install --server-url 'wss://rmm-api.azcomputerguru.com/ws' --api-key 'grmm_3gGYreG0u_QCvt5v3lDVKwLhZDAzF4On' +``` + +Run via ScreenConnect Commands tab (SYSTEM context). Agent heartbeats within ~60 seconds. + +## Active project — folder redirection GPO rollout + +**Goal:** HIPAA-compliant user data storage. Everyone's Documents/Downloads/Desktop/Pictures on `\\CS-SERVER\homes\\`, driven by per-OU folder redirection GPOs. + +**Status:** pattern validated on one user (Sharon Edwards in Life Enrichment). Documents + Downloads successfully redirecting through GPO `CSC - Folder Redirection (LE)` ({889BE7BE-202E-4153-89AD-B5DB62A52D25}). Explorer sidebar working. Detailed journey in `session-logs/2026-04-17-howard-cascades-onboarding-and-folder-redirection.md`. + +**Next:** second LE machine end-to-end tomorrow, then Desktop + other folders, then matching GPOs for other departments. + +### Known traps + +- **Every ProfWiz-migrated user has potentially poisoned `User Shell Folders`** pointing at `C:\Windows\system32\config\systemprofile\...`. Check first, clean before testing redirection. Script: `scripts/hive-cleanup-shellfolders.ps1`. +- **GPMC on Server 2019/2022 writes `fdeploy1.ini` incorrectly when adding + modifying entries in the same editor session.** Workaround: one folder per save, close/reopen editor between adds. +- **Explorer sidebar uses the KnownFolder GUID form** (`{FDD39AD0-...}` for Documents, `{374DE290-...}` for Downloads), not legacy names. CSE may set only the legacy name — manually mirror to the GUID form if sidebar doesn't resolve. Script: `scripts/fix-live-shellfolders.ps1`. +- **Some machines have Documents/Desktop in OneDrive (Known Folder Move).** Don't apply the GPO until OneDrive KFM is unlinked and data is migrated back to local — otherwise data leaves OneDrive's scope and may be orphaned. + +### GPO backups + +On CS-SERVER: `C:\GPO-Backups\pre-fix-20260417-221701\` — broken-state backup ID `9c6ff7c9-0942-4cfb-b4a5-936913a3da87`. `Restore-GPO -BackupId 9c6ff7c9-... -Path C:\GPO-Backups\pre-fix-20260417-221701 -TargetGuid 889be7be-202e-4153-89ad-b5db62a52d25` to roll back. diff --git a/clients/cascades-tucson/scripts/fix-live-shellfolders.ps1 b/clients/cascades-tucson/scripts/fix-live-shellfolders.ps1 new file mode 100644 index 0000000..9f514f8 --- /dev/null +++ b/clients/cascades-tucson/scripts/fix-live-shellfolders.ps1 @@ -0,0 +1,64 @@ +# Live-hive shell-folder repair for a logged-in user whose Documents/Downloads +# sidebar is showing "this file has no associated app" after a folder-redirection +# GPO applies only the legacy (Personal) name but not the modern KnownFolder GUID. +# +# WHEN TO USE +# The Folder Redirection CSE has written the UNC path to `Personal` / etc, +# but the matching GUID value ({FDD39AD0-...} for Documents, +# {374DE290-...} for Downloads) is still pointing at a local path, so +# clicking the sidebar item tries to open the local folder and fails. +# +# HOW TO RUN +# ScreenConnect Backstage PowerShell. User SHOULD be logged in so the hive +# is live. Edit $SID and $UNCBase at the top before running. + +[CmdletBinding()] +param( + [Parameter(Mandatory = $true)] + [string]$SID, + + [Parameter(Mandatory = $true)] + [string]$UNCBase # e.g. '\\CS-SERVER\homes\Sharon.Edwards' +) + +$USF = "HKU\$SID\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" +$SF = "HKU\$SID\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" + +Write-Host "=== BEFORE ===" +reg query "$USF" /v "Personal" 2>$null +reg query "$USF" /v "{FDD39AD0-238F-46AF-ADB4-6C85480369C7}" 2>$null +reg query "$USF" /v "{374DE290-123F-4565-9164-39C4925E467B}" 2>$null + +$docsUNC = "$UNCBase\Documents" +$dlUNC = "$UNCBase\Downloads" + +# Documents - both legacy + GUID so the Explorer sidebar resolves cleanly +reg add "$USF" /v "Personal" /t REG_EXPAND_SZ /d $docsUNC /f | Out-Null +reg add "$USF" /v "{FDD39AD0-238F-46AF-ADB4-6C85480369C7}" /t REG_EXPAND_SZ /d $docsUNC /f | Out-Null +reg add "$SF" /v "Personal" /t REG_SZ /d $docsUNC /f | Out-Null +reg add "$SF" /v "My Documents" /t REG_SZ /d $docsUNC /f | Out-Null + +# Downloads - modern GUID is the one the sidebar uses +reg add "$USF" /v "{374DE290-123F-4565-9164-39C4925E467B}" /t REG_EXPAND_SZ /d $dlUNC /f | Out-Null +reg add "$SF" /v "{374DE290-123F-4565-9164-39C4925E467B}" /t REG_SZ /d $dlUNC /f | Out-Null + +Write-Host "`n=== AFTER ===" +reg query "$USF" /v "Personal" +reg query "$USF" /v "{FDD39AD0-238F-46AF-ADB4-6C85480369C7}" +reg query "$USF" /v "{374DE290-123F-4565-9164-39C4925E467B}" + +# Respawn Explorer for the logged-in user so the new values are picked up. +# Look up by SID rather than by username to avoid locale/spelling issues. +$user = (Get-CimInstance Win32_UserAccount | Where-Object { $_.SID -eq $SID }).Name +if ($user) { + Write-Host "`n=== Restarting Explorer for $user ===" + Get-Process explorer -IncludeUserName -ErrorAction SilentlyContinue | + Where-Object { $_.UserName -like "*\$user" -or $_.UserName -like "$user" } | + ForEach-Object { Write-Host "Killing PID $($_.Id) owner=$($_.UserName)"; Stop-Process -Id $_.Id -Force } + Start-Sleep 3 + Get-Process explorer -IncludeUserName -ErrorAction SilentlyContinue | + Where-Object { $_.UserName -like "*\$user" -or $_.UserName -like "$user" } | + Select-Object Id, UserName, StartTime | Format-Table -AutoSize +} else { + Write-Host "`n[WARN] Could not resolve SID to a username - user may need to sign out and back in for sidebar to refresh." +} diff --git a/clients/cascades-tucson/scripts/hive-cleanup-shellfolders.ps1 b/clients/cascades-tucson/scripts/hive-cleanup-shellfolders.ps1 new file mode 100644 index 0000000..9211106 --- /dev/null +++ b/clients/cascades-tucson/scripts/hive-cleanup-shellfolders.ps1 @@ -0,0 +1,102 @@ +# Per-user NTUSER.DAT shell-folder cleanup for ProfWiz-migrated Cascades users. +# +# WHAT IT DOES +# Finds the user's offline NTUSER.DAT, backs it up, loads the hive, and resets +# any User Shell Folders values that are poisoned with the SYSTEM-profile path +# (C:\Windows\system32\config\systemprofile\...) back to the standard +# %USERPROFILE%\ REG_EXPAND_SZ defaults. Desktop is intentionally NOT +# touched — on machines with a working Desktop reg hack, leaving it alone is +# the safe default. +# +# WHEN TO USE +# ProfWiz-migrated user whose Folder Redirection GPO won't apply cleanly, +# whose logon hangs at "Welcome," or whose Documents/Downloads sidebar shows +# the "this file has no associated app" error. Always verify the hive is +# poisoned FIRST by logging in and reading HKCU\...\User Shell Folders. +# +# HOW TO RUN +# - ScreenConnect Backstage PowerShell (runs as SYSTEM) is the most reliable +# - User MUST be logged OFF (hive loads from NTUSER.DAT on disk; can't be +# locked by an active session) +# - Pass the user's profile path as -ProfilePath, or omit to use the default +# C:\Users\\ +# +# ROLLBACK +# A timestamped backup is written to C:\ProfileBackups\ before any change. +# Restore: Copy-Item -Force (user logged out) + +[CmdletBinding()] +param( + [Parameter(Mandatory = $true)] + [string]$ProfilePath, # e.g. 'C:\Users\Sharon Edwards' + + [string]$BackupDir = 'C:\ProfileBackups', + + [string]$TempHiveName = 'ProfileFix' +) + +$ErrorActionPreference = 'Stop' + +$ntuser = Join-Path $ProfilePath 'NTUSER.DAT' +if (-not (Test-Path $ntuser)) { throw "NTUSER.DAT not found at $ntuser" } + +New-Item -ItemType Directory -Path $BackupDir -Force | Out-Null +$stamp = Get-Date -Format 'yyyyMMdd-HHmmss' +$leaf = Split-Path $ProfilePath -Leaf +$backup = Join-Path $BackupDir "$leaf-NTUSER.DAT.$stamp.bak" +Copy-Item $ntuser $backup -Force +Write-Host "[OK] Backup -> $backup" + +if (Test-Path "Registry::HKEY_USERS\$TempHiveName") { + reg unload "HKU\$TempHiveName" 2>&1 | Out-Null + Start-Sleep 1 +} +$loadResult = reg load "HKU\$TempHiveName" $ntuser 2>&1 +if ($LASTEXITCODE -ne 0) { throw "reg load failed: $loadResult" } +Write-Host "[OK] Hive loaded at HKU\$TempHiveName" + +try { + $USF = "Registry::HKEY_USERS\$TempHiveName\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" + + # Known-poisoned value names + their default REG_EXPAND_SZ targets. + # Desktop is deliberately omitted — don't clobber working redirections. + # Include BOTH the legacy names and the KnownFolder GUID forms so the + # Explorer sidebar resolves to the same place. + $resets = [ordered]@{ + 'Personal' = '%USERPROFILE%\Documents' + 'My Music' = '%USERPROFILE%\Music' + 'My Pictures' = '%USERPROFILE%\Pictures' + 'My Video' = '%USERPROFILE%\Videos' + 'Favorites' = '%USERPROFILE%\Favorites' + '{FDD39AD0-238F-46AF-ADB4-6C85480369C7}' = '%USERPROFILE%\Documents' # Documents KF + '{374DE290-123F-4565-9164-39C4925E467B}' = '%USERPROFILE%\Downloads' # Downloads KF + } + + # Only touch a value if it's CURRENTLY poisoned (points under systemprofile) + # or missing. This keeps working redirections (e.g., UNC paths set by a + # functioning CSE) intact. + $poisonPrefix = 'C:\Windows\system32\config\systemprofile' + + foreach ($name in $resets.Keys) { + $current = (Get-ItemProperty -Path $USF -Name $name -ErrorAction SilentlyContinue).$name + $new = $resets[$name] + + if ($null -eq $current) { + New-ItemProperty -Path $USF -Name $name -Value $new -PropertyType ExpandString -Force | Out-Null + Write-Host " [ADDED] $name = $new" + } elseif ($current -like "$poisonPrefix*") { + Set-ItemProperty -Path $USF -Name $name -Value $new -Type ExpandString + Write-Host " [CHANGED] $name : '$current' -> '$new' (was poisoned)" + } else { + Write-Host " [KEEP] $name = '$current' (not poisoned, leaving alone)" + } + } +} finally { + [gc]::Collect() + Start-Sleep 2 + reg unload "HKU\$TempHiveName" 2>&1 | Out-Null + Write-Host "[OK] Hive unloaded" +} + +Write-Host "`nBackup: $backup" +Write-Host "Rollback: Copy-Item '$backup' '$ntuser' -Force (while user logged out)" diff --git a/clients/cascades-tucson/session-logs/2026-04-17-howard-cascades-onboarding-and-folder-redirection.md b/clients/cascades-tucson/session-logs/2026-04-17-howard-cascades-onboarding-and-folder-redirection.md new file mode 100644 index 0000000..2509185 --- /dev/null +++ b/clients/cascades-tucson/session-logs/2026-04-17-howard-cascades-onboarding-and-folder-redirection.md @@ -0,0 +1,196 @@ +# Cascades of Tucson — Onboarding + Folder Redirection GPO Work + +## Session + +- **Date:** 2026-04-17 (work into early 2026-04-18 UTC) +- **User:** Howard Enos (howard) +- **Machine:** ACG-TECH03L (Howard's laptop) + ScreenConnect into DESKTOP-DLTAGOI (Sharon Edwards, Life Enrichment) + CS-SERVER (DC) +- **Client:** Cascades of Tucson (Syncro ID 20149445) +- **Ticket(s):** Syncro #132 (Life Enrichment GPO) + +--- + +## What we shipped + +### 1. Vault entries (encrypted, pushed to Gitea) + +Added to `D:\vault\clients\cascades-tucson\`: + +- `synology-cascadesds.sops.yaml` — DSM @ `http://192.168.0.120:5000/` — `admin / r3tr0gradE99#` +- `cs-server.sops.yaml` — CS-SERVER login — `sysadmin / r3tr0gradE99#` (IP TBD — update next on-site visit) +- `gururmm-site-main.sops.yaml` — GuruRMM site enrollment key for the CascadesTucson site. **Returned once by the API at site creation, will not be re-issued.** Used when installing the agent on Cascades endpoints. + +### 2. GuruRMM client + site + +| Object | Name | Code | GUID | +|---|---|---|---| +| Client | Cascades of Tucson | CASC | `42e1b0e3-f8b7-4fc5-86bd-06bdbb073b7f` | +| Site | CascadesTucson | GOLD-MOON-4620 | `c157c399-82d3-4581-979a-b9fad70f4fef` | + +Created via `/api/clients` and `/api/sites` on `https://rmm-api.azcomputerguru.com`. Visible in the dashboard at https://rmm.azcomputerguru.com/clients. + +**Note on site naming:** originally created as "Main," renamed to "CascadesTucson" in the dashboard. Vault file name is still `gururmm-site-main.sops.yaml` (filename not updated — content reflects new name). + +### 3. Agents enrolled + +Deployed via **ScreenConnect Commands** using a single PowerShell one-liner: + +```powershell +$u='https://rmm-api.azcomputerguru.com/downloads/gururmm-agent-windows-amd64-latest.exe'; +$d='C:\Windows\Temp\gururmm-agent.exe'; +Invoke-WebRequest $u -UseBasicParsing -OutFile $d; +& $d install --server-url 'wss://rmm-api.azcomputerguru.com/ws' --api-key 'grmm_3gGYreG0u_QCvt5v3lDVKwLhZDAzF4On' +``` + +ScreenConnect Commands runs as SYSTEM, so the service install goes through without UAC. Installer drops binary to `C:\Program Files\GuruRMM\`, config to `C:\ProgramData\GuruRMM\agent.toml`, registers the Windows service, starts it. Heartbeat within ~60 seconds. + +Agents now live under CascadesTucson site: + +| Hostname | Role | Agent ID | +|---|---|---| +| DESKTOP-DLTAGOI | Life Enrichment workstation (Sharon Edwards) | `0ed72c1c-40c7-4bd4-afed-e0bcb198936f` | +| CS-SERVER | Domain controller / file server | `6766e973-e703-47c1-be56-76950290f87c` | + +### 4. GPO edit — `CSC - Folder Redirection (LE)` + +Target GPO: `{889BE7BE-202E-4153-89AD-B5DB62A52D25}` — linked at `OU=Life Enrichment,OU=Departments,DC=cascades,DC=local`. + +Final state after the fix session: +- Documents redirected to `\\CS-SERVER\homes\%USERNAME%\Documents` — GrantExclusive=false, MoveContents=true +- Downloads redirected to `\\CS-SERVER\homes\%USERNAME%\Downloads` — GrantExclusive=false, MoveContents=true +- GPO version bumped from `3` to `8` through the iterations (`ModificationTime` ≈ 22:37 local) +- Backups of both our GPO + the peer reference GPO at `C:\GPO-Backups\pre-fix-20260417-221701\` on CS-SERVER (Broken-GPO Backup ID: `9c6ff7c9-0942-4cfb-b4a5-936913a3da87`) + +--- + +## Root-cause analysis (keep this for other machines) + +Sharon's folder redirection failed for **two stacked reasons**. Both need to be checked on every ProfWiz-migrated user across the domain. + +### Cause 1: GPO GUI-bug — "Grant user exclusive rights" + pre-existing target + +- The original `CSC - Folder Redirection (LE)` GPO had `GrantExclusiveRights=true` on Documents +- The target folder `D:\Homes\Sharon.Edwards\Documents` already existed with INHERITED ACLs (not created by the CSE) +- CSE refused to take over: it needs to own the target to grant exclusive rights — but didn't own it — so it **silently aborted the redirection write and logged no success or failure event** +- Symptom: Event ID 1006 on client showing "has to be redirected" but no following Event ID 101 (success) or 502/602 (failure) +- Fix: uncheck "Grant the user exclusive rights" in the GPO + +**For other departments' GPOs:** always leave "Grant exclusive rights" UNCHECKED unless you're building from scratch with no pre-existing user folders. In an MSP / multi-admin environment it causes more problems than it solves. Share + NTFS ACLs already cover HIPAA access control. + +### Cause 2: ProfWiz migration poisoned NTUSER.DAT + +The user's `HKU\\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders` values were pointing at `C:\Windows\system32\config\systemprofile\Documents` (and Music, Pictures, Video, Favorites, Downloads). That's the LOCAL SYSTEM account's profile — not a Windows default. + +**This happens when:** ProfWiz's NTUSER.DAT SID re-signing overlaps in time with a SYSTEM-context process touching the hive (e.g., `gpupdate /force` run via `PsExec -s` as a "finalizing step" in some migration scripts). SYSTEM's default `User Shell Folders` values leak into the migrated hive before it's re-signed with the domain SID. + +Why it matters for folder redirection: +- CSE reads the **current value** of the shell folder as the source for `MoveContents=true` +- If current value is `C:\Windows\system32\config\systemprofile\Documents`, CSE (running in the user's context) tries to read SYSTEM's folder — access denied, hangs for minutes before giving up +- During that time the user profile service waits on CSE and the logon stalls at "Welcome" with spinning dots +- Eventually CSE gives up, Explorer starts with the registry in a weird partial state, and the user sees "this file has no associated app" when clicking Documents or Downloads in the sidebar + +**Detection:** check `HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders` when the user is logged in. If `Personal`, `My Music`, `My Pictures`, `My Video`, `Favorites`, or the Downloads GUID `{374DE290-123F-4565-9164-39C4925E467B}` point to anything under `C:\Windows\system32\config\systemprofile\`, the hive is poisoned. + +**Remediation (per user):** run the hive-cleanup script (see below) via ScreenConnect Backstage PowerShell while the user is logged off. Sets poisoned values back to `%USERPROFILE%\` defaults (`REG_EXPAND_SZ`). + +--- + +## GPMC behavior we ran into (document this before moving to other departments) + +On Windows Server 2019/2022, GPMC's Folder Redirection snap-in has a bug where **modifying + adding entries in the same save session writes AD attributes correctly but leaves `fdeploy1.ini` in a half-written state**. Specifically: +- `Get-GPOReport` (reads AD) shows the correct `GrantExclusiveRights`, destination, etc. +- But client CSEs read SYSVOL's `fdeploy1.ini`, which was missing the "redirect enabled" bit for newly-added entries +- Runtime flags in the CSE event log (e.g., `Redirection options = 0x1231`) remained identical to pre-edit state even though the AD side said different + +**Workaround sequence that works:** +1. In the GP editor, right-click each folder → Properties → Setting dropdown → "Not configured" → OK. Save. +2. File → Exit the GP editor. Wait ~30 seconds. +3. Reopen the GPO (Edit again). +4. Add Documents: Basic → Create a folder per user under root → root `\\CS-SERVER\homes` → uncheck "Grant user exclusive rights" → leave "Move contents" checked → OK. +5. File → Exit. Wait ~15 seconds. Edit again. +6. Add the next folder (Downloads, etc.) — same settings → OK. +7. File → Exit. + +The close-and-reopen between folder adds is the trick. Don't add multiple folders in one editor session — that triggers the half-write bug. + +After the edit, verify via RMM on the DC: +- `fdeploy1.ini` at `C:\Windows\SYSVOL\sysvol\cascades.local\Policies\{GUID}\User\Documents & Settings\fdeploy1.ini` has BOTH entries with `FullPath=\\...\%USERNAME%\` and `Flags=` in a sane range (≠ 1000; working values we've seen: 4, 1001, 1021) +- `Get-GPO` shows bumped `User.DSVersion` and matching `User.SysvolVersion` + +--- + +## Explorer sidebar disconnect (Known Folders vs legacy names) + +Discovered that setting `User Shell Folders\Personal` alone **is not enough** on Windows 10/11. Explorer's sidebar (the tree on the left) uses the modern Known Folder API — `SHGetKnownFolderPath(FOLDERID_Documents)` — which resolves via the **GUID-form value** `{FDD39AD0-238F-46AF-ADB4-6C85480369C7}`, not the legacy `Personal`. + +On Sharon, after the CSE ran: +- `Personal` = `\\CS-SERVER\homes\Sharon.Edwards\Documents` ✓ (set by CSE) +- `{FDD39AD0-238F-46AF-ADB4-6C85480369C7}` = `%USERPROFILE%\Documents` ✗ (still local) + +Because these disagreed, clicking Documents in the sidebar tried to open the local path, which had MoveContents-side-effect attributes set on it, and produced the "no associated app" error. + +**Fix that worked (applied via Backstage while she was logged in):** set the modern GUID values to match: + +``` +HKU\\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders + Personal = \\CS-SERVER\homes\Sharon.Edwards\Documents (REG_EXPAND_SZ) + {FDD39AD0-238F-46AF-ADB4-6C85480369C7} = \\CS-SERVER\homes\Sharon.Edwards\Documents (REG_EXPAND_SZ) + {374DE290-123F-4565-9164-39C4925E467B} = \\CS-SERVER\homes\Sharon.Edwards\Downloads (REG_EXPAND_SZ) +``` + +And the mirrored `Shell Folders` key with `REG_SZ` resolved paths. Then kill her Explorer process — it respawns with correct paths. + +**For the GPO route (the long-term fix):** recent folder redirection CSEs *should* set both the legacy and GUID forms. On this environment, the legacy-only update is happening. If it's consistent across Cascades we may need to add a logon-script fallback that enforces GUID-form parity, or file the underlying Windows bug. + +--- + +## Per-user hive cleanup script (save — we'll run this on every ProfWiz-migrated machine) + +Runs as SYSTEM (ScreenConnect Backstage). User must be logged OFF so NTUSER.DAT is unloaded. Script backs up NTUSER.DAT, loads the hive, resets poisoned values to `%USERPROFILE%\` defaults, unloads. + +See `clients/cascades-tucson/scripts/hive-cleanup-shellfolders.ps1` in the repo. + +--- + +## Operational findings / glitches + +- **GuruRMM agent command executor wedge:** On DLTAGOI, a PowerShell diagnostic command that touched `Get-WinEvent` during a hung logon caused the agent's command executor to lock up. Subsequent commands stayed "pending" indefinitely, even after cancel + machine reboot. Heartbeat continued fine (separate thread). Other agents (CS-SERVER) processed commands normally. Workaround: ran cleanup scripts via ScreenConnect Backstage instead. File this against GuruRMM as "stuck command executor after user-context PS hang needs agent-service restart / doesn't recover on reboot." +- **GPMC `fdeploy1.ini` half-write bug** — see above. +- **Redirection target folders from earlier manual attempts:** there was a stray `_frtest.txt` and empty `Documents` directory under `D:\Homes\Sharon.Edwards\` from prior manual tests. These triggered the "grant exclusive rights" failure. + +--- + +## Open items / tomorrow's work + +1. **Desktop cleanup on DLTAGOI** — the working Desktop redirection is via a **manual reg hack** (`User Shell Folders\Desktop` set directly to UNC), not the GPO. Need to: + - Add Desktop to the GPO with same settings as Documents/Downloads + - Remove the Desktop reg hack (let the GPO drive it) + - Verify Desktop sidebar works the same way (likely also needs the `{B4BFCC3A-DB2C-424C-B029-7FE99A87C641}` GUID form set) +2. **Additional folders** — add Pictures, Music, Videos, Favorites to the GPO once Desktop is proven stable +3. **Second Life Enrichment machine** — apply the same end-to-end tomorrow. If it works cleanly, then: +4. **Other departments** — build matching GPOs (Nursing, Admin, Maintenance, etc.) linked to each OU, same target root `\\CS-SERVER\homes` pattern, same "uncheck exclusive rights" discipline +5. **OneDrive conflict strategy** — some Cascades machines have Documents/Desktop already redirected into OneDrive. Need a plan: + - Detect OneDrive-backed Known Folder Move (KFM) state (registry: `HKCU\Software\Microsoft\OneDrive\...\ScopeIdToMountPointPathCache` etc.) + - Migrate content from OneDrive back to local `C:\Users\\Documents` (via `robocopy` preserving timestamps + ACLs) + - Unlink OneDrive KFM (Settings → Backup → Stop backup — or the equivalent registry / powershell automation) + - THEN let the GPO redirect to `\\CS-SERVER\homes` + - Decision needed: do we keep OneDrive installed (for real OneDrive usage) or uninstall? HIPAA BAA status of the Cascades M365 tenant will inform this. +6. **HIPAA hardening** (after folder redirection is stable): + - `Set-SmbShare -Name homes -EncryptData $true` on CS-SERVER + - Enable file-access auditing on `D:\Homes` + - Confirm BitLocker status on CS-SERVER's D: drive + +--- + +## Quick reference — Cascades infrastructure (current-known) + +| Resource | Address | Credential path in vault | +|---|---|---| +| pfSense firewall | 192.168.0.1 | `clients/cascades-tucson/pfsense-firewall.sops.yaml` | +| Synology NAS `cascadesds` | 192.168.0.120:5000 | `clients/cascades-tucson/synology-cascadesds.sops.yaml` | +| CS-SERVER (DC + file server) | reachable at 192.168.2.254 from DLTAGOI on Wi-Fi-2; `cascades.local` domain | `clients/cascades-tucson/cs-server.sops.yaml` | +| DLTAGOI (Sharon Edwards test machine) | 10.0.20.72 on Wi-Fi-2 | n/a (domain-joined) | +| GuruRMM site enrollment key | — | `clients/cascades-tucson/gururmm-site-main.sops.yaml` | +| `svc-audit-upload` service account | — | `clients/cascades-tucson/svc-audit-upload.sops.yaml` | + +Syncro customer record: **20149445** — primary contact Meredith Kuhn (meredith.kuhn@cascadestucson.com, 520-886-3171). Full contact list + other creds (Wi-Fi, KPAX, M365 admin, UniFi MACs, GoDaddy) in the Syncro notes field for customer 20149445.