sync: auto-sync from HOWARD-HOME at 2026-06-29 22:26:40
Author: Howard Enos Machine: HOWARD-HOME Timestamp: 2026-06-29 22:26:40
This commit is contained in:
43
.ad_cg.tsv
Normal file
43
.ad_cg.tsv
Normal file
@@ -0,0 +1,43 @@
|
||||
Thelma Abainza t.abainza@cascadestucson.com True
|
||||
|
||||
Juan Andrade j.andrade@cascadestucson.com True
|
||||
|
||||
Ashli Atwood a.atwood@cascadestucson.com True
|
||||
|
||||
Karina Aziakpo k.aziakpo@cascadestucson.com True
|
||||
|
||||
Maia Baker m.baker@cascadestucson.com True
|
||||
|
||||
Patricia Camarena Doran p.doran@cascadestucson.com True
|
||||
|
||||
Sarah Carroll s.carroll@cascadestucson.com True
|
||||
|
||||
Niel Castro n.castro@cascadestucson.com False
|
||||
|
||||
Jahmeka Clarke j.clarke@cascadestucson.com True
|
||||
|
||||
Roseline Cooper r.cooper@cascadestucson.com True
|
||||
|
||||
Jinnelle Dittbenner j.dittbenner@cascadestucson.com True
|
||||
|
||||
Espe Esperance e.esperance@cascadestucson.com True
|
||||
|
||||
Diana Fierros d.fierros@cascadestucson.com True
|
||||
|
||||
Richard Flores r.flores@cascadestucson.com True
|
||||
|
||||
Kasey Flores k.flores@cascadestucson.com True
|
||||
|
||||
Luriz Fuster l.fuster@cascadestucson.com True
|
||||
|
||||
Jen Higdon j.higdon@cascadestucson.com True
|
||||
|
||||
Luke Hogan l.hogan@cascadestucson.com True
|
||||
|
||||
Zeke Huerta e.huerta@cascadestucson.com True
|
||||
|
||||
Cole Johnson c.johnson@cascadestucson.com True
|
||||
|
||||
Barb Johnson b.johnson@cascadestucson.com True
|
||||
|
||||
Mary Kariuki m.kariuki@cascadestucson.com True
|
||||
|
91
.alis_join.py
Normal file
91
.alis_join.py
Normal file
@@ -0,0 +1,91 @@
|
||||
import json, re
|
||||
|
||||
def norm(s):
|
||||
return re.sub(r'[^a-z]', '', (s or '').lower())
|
||||
|
||||
alis = json.load(open('.alis_staff.json'))
|
||||
# ALIS staff: list of dicts
|
||||
arecs = []
|
||||
for s in alis:
|
||||
arecs.append({
|
||||
'first': s.get('firstName','') or '',
|
||||
'last': s.get('lastName','') or '',
|
||||
'nick': s.get('nickName','') or '',
|
||||
'job': s.get('jobRole') or '(none)',
|
||||
'status': s.get('status',''),
|
||||
'email': s.get('primaryEmail') or '',
|
||||
})
|
||||
|
||||
def is_cg(job):
|
||||
return 'caregiver' in (job or '').lower()
|
||||
|
||||
# Load AD caregivers
|
||||
ad = []
|
||||
for line in open('.ad_cg.tsv'):
|
||||
line=line.rstrip('\n')
|
||||
if not line.strip(): continue
|
||||
parts=line.split('\t')
|
||||
if len(parts)<4: continue
|
||||
gn,sn,upn,en=parts[0],parts[1],parts[2],parts[3]
|
||||
ad.append({'gn':gn,'sn':sn,'upn':upn,'enabled':en})
|
||||
|
||||
def find_alis(gn, sn):
|
||||
# match by last-name token overlap, then by first name / nickname
|
||||
ad_last_tokens = set(t for t in norm(sn) and norm(sn).split() or []) # not used
|
||||
ad_sn = norm(sn); ad_gn = norm(gn)
|
||||
# try surname tokens
|
||||
sn_tokens = [norm(t) for t in sn.split() if norm(t)]
|
||||
cands=[]
|
||||
for r in arecs:
|
||||
a_sn = norm(r['last'])
|
||||
a_sn_tokens=[norm(t) for t in r['last'].split() if norm(t)]
|
||||
# surname match: any shared token or containment
|
||||
shared = any(t in a_sn_tokens for t in sn_tokens) or ad_sn==a_sn or ad_sn in a_sn or a_sn in ad_sn
|
||||
if shared:
|
||||
cands.append(r)
|
||||
# disambiguate by first name / nick if multiple
|
||||
if len(cands)>1:
|
||||
fn_match=[r for r in cands if norm(r['first'])==ad_gn or norm(r['nick'])==ad_gn or ad_gn in (norm(r['first'])+norm(r['nick'])) ]
|
||||
if fn_match: return fn_match
|
||||
return cands
|
||||
|
||||
print("=== AD caregiver -> ALIS match ===")
|
||||
print(f"{'AD NAME':28} {'UPN':40} {'ALIS jobRole':34} {'ALIS status'}")
|
||||
matched_alis_ids=set()
|
||||
ad_only=[]; ad_other=[]; ad_cg=[]
|
||||
for u in ad:
|
||||
name=f"{u['gn']} {u['sn']}"
|
||||
if u['upn'].startswith('pilot.test'):
|
||||
continue
|
||||
if u['enabled']=='False':
|
||||
continue
|
||||
cands=find_alis(u['gn'],u['sn'])
|
||||
if not cands:
|
||||
print(f"{name:28} {u['upn']:40} {'-- NOT FOUND IN ALIS (Hired) --':34}")
|
||||
ad_only.append(name); continue
|
||||
# pick a caregiver candidate if present else first
|
||||
cg=[c for c in cands if is_cg(c['job'])]
|
||||
pick = cg[0] if cg else cands[0]
|
||||
tag = pick['job']
|
||||
print(f"{name:28} {u['upn']:40} {tag:34} {pick['status']}")
|
||||
if is_cg(pick['job']): ad_cg.append(name)
|
||||
else: ad_other.append((name, pick['job']))
|
||||
|
||||
print()
|
||||
print(f"AD caregivers that ARE ALIS caregivers: {len(ad_cg)}")
|
||||
print(f"AD caregivers with OTHER ALIS title (ignore per Howard): {len(ad_other)}")
|
||||
for n,j in ad_other: print(f" {n:28} -> {j}")
|
||||
print(f"AD caregivers NOT FOUND in ALIS Hired: {len(ad_only)}")
|
||||
for n in ad_only: print(f" {n}")
|
||||
|
||||
# ALIS caregivers with no AD caregiver account
|
||||
print()
|
||||
print("=== ALIS caregivers (jobRole~caregiver) with NO AD caregiver account ===")
|
||||
ad_norm=set(norm(u['sn']).split()[-1] if u['sn'] else '' for u in ad)
|
||||
ad_last=[norm(t) for u in ad for t in u['sn'].split()]
|
||||
for r in arecs:
|
||||
if not is_cg(r['job']): continue
|
||||
a_tokens=[norm(t) for t in r['last'].split()]
|
||||
if any(t in ad_last for t in a_tokens):
|
||||
continue
|
||||
print(f" {r['first']} {r['last']:22} job={r['job']:34} status={r['status']} email={r['email']}")
|
||||
2197
.alis_staff.json
Normal file
2197
.alis_staff.json
Normal file
File diff suppressed because it is too large
Load Diff
11
.alis_verify.py
Normal file
11
.alis_verify.py
Normal file
@@ -0,0 +1,11 @@
|
||||
import json, re
|
||||
def norm(s): return re.sub(r'[^a-z]','',(s or '').lower())
|
||||
alis=json.load(open('.alis_staff.json'))
|
||||
none_group=["Atwood","Baker","Fierros","Flores","Hogan","Huerta","Kariuki","Lopez","Mendoza","Reed","Tate","Williford"]
|
||||
firstmap={"Flores":"Kasey","Fierros":"Diana"} # disambiguate (Richard Flores is Med Tech)
|
||||
for sn in none_group:
|
||||
cands=[s for s in alis if norm(sn) in norm(s.get('lastName','')) or norm(s.get('lastName','')) in norm(sn)]
|
||||
print(f"AD '{sn}':")
|
||||
if not cands: print(" (no ALIS staff with this surname)")
|
||||
for c in cands:
|
||||
print(f" ALIS: {c.get('firstName','')} {c.get('lastName','')} | job={c.get('jobRole') or '(none)'} | status={c.get('status')}")
|
||||
@@ -115,3 +115,91 @@ Howard provided the Syncro ticket the Carrie-machine work will be billed to once
|
||||
**#32368 (id 111999527)** — Rednour Law. Confirmed read-only that it belongs to customer
|
||||
1224246 and matches the scope (new central-hub/file-share machine for Carrie + reception
|
||||
upgrade). No billing entered yet — billing happens at completion, via `/syncro`.
|
||||
|
||||
## Update: ~22:30 PT — ROOT CAUSE FOUND + UPGRADE SUCCEEDED (live over GuruRMM)
|
||||
|
||||
**Outcome: REDNOURCARRIEVI (rednourcarrievirt) successfully upgraded to Windows 11 25H2
|
||||
(build 26200).** Root cause of the prior failures: a **corrupt Win11 install image**.
|
||||
|
||||
### GuruRMM IS working for Rednour (correcting earlier session note)
|
||||
Contrary to the earlier "RMM doesn't work for Rednour" note, the GuruRMM agent on this box
|
||||
(`8e4e2221-7e2a-4a6f-9eda-864568539961`, hostname `rednourcarrievirt`, agent v0.6.66) is
|
||||
**online and executing commands fine**. All diagnosis below was done live over `/rmm`. The
|
||||
agent record's `is_connected` field returns null, but `status` = "online" and commands
|
||||
complete exit 0. (The earlier "RMM didn't work" likely referred to the Mac enrollment issue,
|
||||
not this Windows box.) The client filter on `/api/agents` uses `client_name == "Rednour Law
|
||||
Offices"` (not "rednour") — search by hostname.
|
||||
|
||||
### Root cause (from setuperr.log, pulled live)
|
||||
The `0x8007000D` SAFE_OS error is only the final rollup. The real, upstream error:
|
||||
```
|
||||
SPWIMCallback: Error in apply of ...\WinSxS\...kernelstreaming...10.0.26100.6584...\ks.sys.
|
||||
GLE [1392] <- ERROR_FILE_CORRUPT
|
||||
CApplyWIM: Failure while applying image 6 for <Install.wim>. Error 0x80070570
|
||||
-> Operation failed -> Failed execution phase Safe OS. Error: 0x8007000D
|
||||
```
|
||||
`ks.sys` (kernel-streaming driver) failed to decompress from the WIM with
|
||||
`ERROR_FILE_CORRUPT` — deterministically, the SAME file every attempt.
|
||||
|
||||
### How it was proven (not guessing)
|
||||
1. First attempt's media was under `C:\Users\Carrie\OneDrive - Rednour Law\Desktop\...` — the
|
||||
`Install.wim` there threw `0x80070780` (ERROR_CANT_ACCESS_FILE) because OneDrive served a
|
||||
cloud placeholder that WinPE/SAFE_OS (OneDrive not running) couldn't read. Howard MOVED the
|
||||
extracted folder to `C:\temp\Win11_25H2_English_x64` — fixed the access error but the
|
||||
`ks.sys` `0x80070570` corruption persisted (same bytes moved along).
|
||||
2. Hashed the extracted `install.wim`: SHA256
|
||||
`9AD2EF7251AED36BCF5E36D4F067B5277C205ED02E3FDFA354069505214C7D54`.
|
||||
3. Mounted the original desktop `.iso` and hashed ITS `install.wim` (`F:\sources\install.wim`)
|
||||
= **identical hash** to the extracted copy. Identical bytes in both = the **download itself
|
||||
was corrupt**, not the extraction. Disk health checked: WD Green SN350 1TB SSD = Healthy/OK,
|
||||
so not a failing-disk read fault. Deterministic same-file CRC failure = bad source image.
|
||||
|
||||
### Fix
|
||||
Re-download via **Media Creation Tool** (validates its own download integrity). New media:
|
||||
`C:\temp\Windows.iso` (6.39 GB, ESD-based, mounted drive labeled `ESD-ISO`, uses
|
||||
`install.esd` not `install.wim`). Ran `setup.exe` from the mounted ISO. Watched live over RMM:
|
||||
down-level apply climbed 28%->36%->46%->50%->68% with NO `ks.sys`/`0x80070570` (all 3 prior
|
||||
attempts died at ~49%), rebooted into SAFE_OS, applied offline, booted into Win11.
|
||||
|
||||
### Post-upgrade verified state (build 26200 / 25H2)
|
||||
- OS: Windows 11 Pro, build 26200, DisplayVersion 25H2. Reboot pending: No. Setup running: No.
|
||||
- `C:\Windows.old` present -> 10-day rollback window (do NOT run Disk Cleanup until apps verified).
|
||||
- Datto AV (`EndpointProtectionService`) auto-restored Running after reboot.
|
||||
- Defender RTP = False -> EXPECTED, Datto AV is the registered primary AV on this box.
|
||||
|
||||
### "endpointprotection.exe" identification (Howard asked)
|
||||
The `endpointprotection` process in Task Manager =
|
||||
`C:\Program Files\infocyte\agent\dattoav\Endpoint Protection SDK\endpointprotection.exe`,
|
||||
service `EndpointProtectionService` ("Endpoint Protection Service", Auto/Running). It is
|
||||
**Datto AV** (the AV engine inside the Datto EDR/Infocyte agent) — ACG-managed, legitimate,
|
||||
not malware. Datto tenant azcomp4587. To pause for an upgrade: `Stop-Service
|
||||
EndpointProtectionService -Force` (Auto-start; returns on reboot).
|
||||
|
||||
## Key Decisions (this update)
|
||||
- Diagnosed entirely over GuruRMM rather than waiting for hands-on log retrieval, after
|
||||
confirming the agent executes commands on this box.
|
||||
- Hash-compared ISO vs extracted `install.wim` to decisively distinguish a corrupt DOWNLOAD
|
||||
from extraction corruption / failing hardware before recommending a 7 GB re-download.
|
||||
- Recommended Media Creation Tool (integrity-validated) over a plain browser ISO re-download to
|
||||
avoid another silently-corrupt image.
|
||||
- Did NOT unilaterally stop Datto AV mid-run — corrupt download was the proven cause, AV was
|
||||
secondary; flagged it instead.
|
||||
|
||||
## Problems Encountered (this update)
|
||||
- Win11 upgrade failed 3x at SAFE_OS/APPLY_IMAGE `0x8007000D`. Root cause = corrupt download
|
||||
(`ks.sys` `0x80070570`). Resolved with fresh Media Creation Tool media.
|
||||
- PowerShell variable-expansion trap: `"C:\$WINDOWS.~BT"` in a DOUBLE-quoted PS string expands
|
||||
`$WINDOWS` to empty -> `C:\.~BT`, so Test-Path falsely returned "folder gone." Fix: escape as
|
||||
`"C:\`$WINDOWS.~BT"` (backtick) or single-quote the path. (logged as friction)
|
||||
- Bash tool default timeout is 120000ms (2 min); long RMM watch loops got cut off twice until
|
||||
the `timeout` param was set to 600000.
|
||||
|
||||
## Update — Pending / Incomplete Tasks (supersedes earlier "tonight" plan)
|
||||
- [DONE] Win11 upgrade on Carrie's machine (build 26200/25H2).
|
||||
- Verify post-upgrade that the firm's SMB shares (`Documents`, Time Matters, Timeslips) and
|
||||
local accounts (`carrie`, `nick`, `emma`) survived the feature upgrade (sharing/firewall can
|
||||
reset). Nick's Mac mounts `smb://192.168.10.194/Documents`.
|
||||
- Confirm with Carrie that Time Matters / Timeslips / WordPerfect work on Win11 before the
|
||||
10-day `Windows.old` rollback window lapses (don't Disk-Cleanup it until then).
|
||||
- BILLING: enter labor on Syncro #32368 (id 111999527) via `/syncro` now that work is complete.
|
||||
- Optional: pause Datto AV (`EndpointProtectionService`) for any future feature upgrades.
|
||||
|
||||
@@ -17,6 +17,10 @@ Categories (the `[type]` tag): _(none)_ = skill/command execution failure ·
|
||||
|
||||
<!-- Append entries below this line -->
|
||||
|
||||
2026-06-30 | Howard-Home | bash/env | [friction] Bash tool default timeout 120000ms cut off long RMM watch loops twice; set timeout param to 600000 for multi-minute monitoring.
|
||||
|
||||
2026-06-30 | Howard-Home | powershell/env | [friction] "C:.~BT" in a double-quoted PS string expands $WINDOWS to empty -> C:.~BT; Test-Path falsely reports folder missing. Fix: backtick-escape (`$) or single-quote the path.
|
||||
|
||||
2026-06-29 | GURU-5070 | remediation-tool/graph | [friction] Tenant Admin app 403s on group DELETE (has GroupMember write, not Group.ReadWrite.All); use User Manager app for M365 group deletion [ctx: tenant=birthbiologic op=group-delete]
|
||||
|
||||
2026-06-29 | GURU-5070 | rmm/rsync-cygwin | [friction] cwRsync (cygwin) on AD2 misreads a Windows 'C:path' DESTINATION as a remote host; pulls silently fail. Use /cygdrive/c/... for local src AND dst [ctx: host=AD2 ref=dataforth-dos-sync]
|
||||
|
||||
Reference in New Issue
Block a user