cascades: CS-SERVER preflight verified + Synology discovery complete
CS-SERVER post-reboot verification: time sync, TLS 1.2 enforcement, and Windows Server Backup feature all persisted cleanly. dcdiag clean. Ready for Entra Connect install. Synology cascadesDS permission inventory captured via DSM API (SSH disabled by default on Synology). 35 users, 4 groups, 10 shares. Analysis identifies 7 shared-account role logins (HIPAA violation), 8 departed-employee accounts to clean up, and 4 shares needing Meredith-side confirmation before migration (pacs most sensitive). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,243 @@
|
||||
"""Parse the raw Synology DSM API discovery dump into a clean inventory doc.
|
||||
|
||||
Input: docs/migration/synology-permission-inventory-raw.md
|
||||
Output: docs/migration/synology-permission-inventory.md (clean digest + mapping table)
|
||||
"""
|
||||
import json
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
RAW = Path('clients/cascades-tucson/docs/migration/synology-permission-inventory-raw.md')
|
||||
OUT = Path('clients/cascades-tucson/docs/migration/synology-permission-inventory.md')
|
||||
|
||||
|
||||
def extract_json_after(label, text):
|
||||
"""Find the first JSON object after '--- <label> ---' marker using bracket-matching."""
|
||||
idx = text.find(f'--- {label} ---')
|
||||
if idx < 0:
|
||||
return None
|
||||
start = text.find('{', idx)
|
||||
if start < 0:
|
||||
return None
|
||||
depth = 0
|
||||
in_str = False
|
||||
esc = False
|
||||
for i in range(start, len(text)):
|
||||
c = text[i]
|
||||
if esc:
|
||||
esc = False
|
||||
continue
|
||||
if c == "\\":
|
||||
esc = True
|
||||
continue
|
||||
if c == '"':
|
||||
in_str = not in_str
|
||||
continue
|
||||
if in_str:
|
||||
continue
|
||||
if c == '{':
|
||||
depth += 1
|
||||
elif c == '}':
|
||||
depth -= 1
|
||||
if depth == 0:
|
||||
return text[start:i + 1]
|
||||
return None
|
||||
|
||||
|
||||
def find_all_json_after(label_pattern, text):
|
||||
"""Find every JSON block whose label matches the regex pattern."""
|
||||
results = []
|
||||
for m in re.finditer(r'--- (' + label_pattern + r') ---\n', text):
|
||||
label = m.group(1)
|
||||
body = extract_json_after(label, text[m.start():])
|
||||
if body is None:
|
||||
continue
|
||||
try:
|
||||
results.append((label, json.loads(body)))
|
||||
except json.JSONDecodeError:
|
||||
pass
|
||||
return results
|
||||
|
||||
|
||||
def main():
|
||||
content = RAW.read_text(encoding='utf-8')
|
||||
content = re.sub(r'\n{2,}', '\n', content)
|
||||
|
||||
# USERS
|
||||
users_obj = json.loads(extract_json_after('SYNO.Core.User list', content))
|
||||
users = users_obj.get('data', {}).get('users', [])
|
||||
|
||||
# GROUPS
|
||||
groups_obj = json.loads(extract_json_after('SYNO.Core.Group list', content))
|
||||
groups = groups_obj.get('data', {}).get('groups', [])
|
||||
|
||||
# SHARES
|
||||
shares_obj = json.loads(extract_json_after('SYNO.Core.Share list', content))
|
||||
shares = shares_obj.get('data', {}).get('shares', [])
|
||||
|
||||
# PER-SHARE PERMISSIONS
|
||||
perms = find_all_json_after(r"share '[^']+' - local (?:user|group) permissions", content)
|
||||
|
||||
# Build a lookup: share_name -> {'users': {name: flags}, 'groups': {name: flags}}
|
||||
share_perms = {}
|
||||
for label, obj in perms:
|
||||
m = re.match(r"share '([^']+)' - local (user|group) permissions", label)
|
||||
if not m:
|
||||
continue
|
||||
sname, scope = m.group(1), m.group(2)
|
||||
share_perms.setdefault(sname, {'user': {}, 'group': {}})
|
||||
for item in obj.get('data', {}).get('items', []):
|
||||
nm = item.get('name', '?')
|
||||
share_perms[sname][scope][nm] = {
|
||||
'admin': item.get('is_admin', False),
|
||||
'deny': item.get('is_deny', False),
|
||||
'ro': item.get('is_readonly', False),
|
||||
'rw': item.get('is_writable', False),
|
||||
'custom': item.get('is_custom', False),
|
||||
}
|
||||
|
||||
# Effective write-access table: for each share, who can actually write (writable OR admin) AND not denied
|
||||
def effective(flags):
|
||||
if flags['deny']:
|
||||
return 'DENY'
|
||||
if flags['rw']:
|
||||
return 'RW'
|
||||
if flags['admin']:
|
||||
return 'Admin(full)'
|
||||
if flags['ro']:
|
||||
return 'RO'
|
||||
return '-'
|
||||
|
||||
# Write the digest
|
||||
out_lines = []
|
||||
out_lines.append('# Synology cascadesDS — Permission Inventory (2026-04-22 via DSM API)')
|
||||
out_lines.append('')
|
||||
out_lines.append('**Source:** `docs/migration/synology-permission-inventory-raw.md`')
|
||||
out_lines.append('**Method:** DSM HTTP API v7 via CS-SERVER GuruRMM agent (SSH not enabled on Synology as of 2026-04-22)')
|
||||
out_lines.append('')
|
||||
out_lines.append('## Summary counts')
|
||||
out_lines.append('')
|
||||
out_lines.append(f'- Synology local users: **{len(users)}**')
|
||||
out_lines.append(f'- Synology local groups: **{len(groups)}**')
|
||||
out_lines.append(f'- Shares: **{len(shares)}**')
|
||||
out_lines.append('')
|
||||
|
||||
# Users
|
||||
out_lines.append('## Users')
|
||||
out_lines.append('')
|
||||
out_lines.append('| Name | UID | Expired | Email | Description | Groups |')
|
||||
out_lines.append('|---|---:|---|---|---|---|')
|
||||
for u in sorted(users, key=lambda x: x.get('name', '').lower()):
|
||||
name = u.get('name', '?')
|
||||
uid = u.get('uid', '-')
|
||||
expired = 'yes' if u.get('expired') in ('now', 'expired', True) else 'no'
|
||||
email = u.get('email', '') or ''
|
||||
desc = (u.get('description', '') or '').replace('|', r'\|')
|
||||
groups_list = u.get('additional', {}).get('groups', []) if isinstance(u.get('additional'), dict) else []
|
||||
groups_str = ', '.join(groups_list) if groups_list else '-'
|
||||
out_lines.append(f'| `{name}` | {uid} | {expired} | {email} | {desc} | {groups_str} |')
|
||||
out_lines.append('')
|
||||
|
||||
# Groups
|
||||
out_lines.append('## Groups')
|
||||
out_lines.append('')
|
||||
out_lines.append('| Name | GID | Type | Description | Members |')
|
||||
out_lines.append('|---|---:|---|---|---|')
|
||||
for g in groups:
|
||||
name = g.get('name', '?')
|
||||
gid = g.get('gid', '-')
|
||||
gtype = g.get('type', '-') or '-'
|
||||
desc = g.get('description', '') or ''
|
||||
members = g.get('additional', {}).get('members', []) if isinstance(g.get('additional'), dict) else []
|
||||
member_names = ', '.join([m.get('name', '?') if isinstance(m, dict) else str(m) for m in members]) or '(unable to enumerate via API — error 3201)'
|
||||
out_lines.append(f'| `{name}` | {gid} | {gtype} | {desc} | {member_names} |')
|
||||
out_lines.append('')
|
||||
out_lines.append('> Note: DSM API `SYNO.Core.Group.Member` returned error 3201 for all groups with this API path; membership was only partially available via the `members` additional field on the group list call. Full membership requires DSM web UI or CLI `synogroup --get <name>` via SSH.')
|
||||
out_lines.append('')
|
||||
|
||||
# Shares + permissions
|
||||
out_lines.append('## Shares')
|
||||
out_lines.append('')
|
||||
out_lines.append('| Share | Volume Path | Hidden | Description |')
|
||||
out_lines.append('|---|---|---|---|')
|
||||
for s in shares:
|
||||
name = s.get('name', '?')
|
||||
vol = s.get('vol_path', '') or s.get('additional', {}).get('vol_path', '') or ''
|
||||
hidden = s.get('additional', {}).get('hidden', False) if isinstance(s.get('additional'), dict) else False
|
||||
desc = (s.get('additional', {}).get('desc', '') or '') if isinstance(s.get('additional'), dict) else ''
|
||||
out_lines.append(f'| `{name}` | {vol} | {hidden} | {desc} |')
|
||||
out_lines.append('')
|
||||
|
||||
# Effective permissions per share (write-capable or explicit-deny users/groups)
|
||||
out_lines.append('## Effective share permissions')
|
||||
out_lines.append('')
|
||||
out_lines.append('"Admin(full)" means the account inherits full control via administrators-group membership. "RW" means explicitly writable. "DENY" means explicitly denied (wins over everything else in Synology ACL order). Blank / absent means no explicit permission (effectively no access beyond what the users group grants).')
|
||||
out_lines.append('')
|
||||
|
||||
# Identity sets to call out
|
||||
known_current_employees = {
|
||||
'Ashley Jensen', 'CasAdmin201', 'ChristinaDupras', 'Crystal Rodriguez',
|
||||
'Crystal Suszek', 'Dining Manager', 'JD Martin', 'John Trozzi',
|
||||
'Karen Rossini', 'Lois Lane', 'Lupe Sanchez', 'Megan Hiatt',
|
||||
'meredith kuhn', 'Shelby Trozzi', 'Stephanie Devin', 'Susan Hicks',
|
||||
'Veronica'
|
||||
}
|
||||
known_departed = {
|
||||
'Amber M Lee', 'Ann Dery', 'Anna Pitzlin', 'Britney Thompson',
|
||||
'Haris Durut', 'Monica RamirezRossette', 'Nela Durut-Azizi',
|
||||
'Tamra Johnson'
|
||||
}
|
||||
role_accounts = {
|
||||
'Accounting', 'Dining Manager', 'Front Desk', 'Memcare Receptionist',
|
||||
'mcnurse', 'memcarenurse', 'Nurse Tower'
|
||||
}
|
||||
service_or_admin = {'admin', 'guest', 'guru', 'VPNClient'}
|
||||
|
||||
for sname in sorted(share_perms.keys()):
|
||||
out_lines.append(f'### Share: `{sname}`')
|
||||
out_lines.append('')
|
||||
|
||||
# Groups first
|
||||
g_perms = share_perms[sname]['group']
|
||||
out_lines.append('**Groups:**')
|
||||
out_lines.append('')
|
||||
out_lines.append('| Group | Effective |')
|
||||
out_lines.append('|---|---|')
|
||||
for gname in sorted(g_perms.keys()):
|
||||
out_lines.append(f'| `{gname}` | {effective(g_perms[gname])} |')
|
||||
out_lines.append('')
|
||||
|
||||
# Users with non-default effective permission
|
||||
u_perms = share_perms[sname]['user']
|
||||
nondefault = {n: f for n, f in u_perms.items()
|
||||
if f['rw'] or f['ro'] or f['deny'] or f['admin']}
|
||||
if nondefault:
|
||||
out_lines.append('**Users with explicit permission:**')
|
||||
out_lines.append('')
|
||||
out_lines.append('| User | Effective | Status |')
|
||||
out_lines.append('|---|---|---|')
|
||||
for n in sorted(nondefault.keys(), key=lambda x: x.lower()):
|
||||
eff = effective(nondefault[n])
|
||||
if n in known_departed:
|
||||
status = 'DEPARTED'
|
||||
elif n in role_accounts:
|
||||
status = 'ROLE (HIPAA concern)'
|
||||
elif n in service_or_admin:
|
||||
status = 'service/admin'
|
||||
elif n in known_current_employees:
|
||||
status = 'current'
|
||||
else:
|
||||
status = '?'
|
||||
out_lines.append(f'| `{n}` | {eff} | {status} |')
|
||||
out_lines.append('')
|
||||
else:
|
||||
out_lines.append('*(No user-level overrides — share access is group-based only.)*')
|
||||
out_lines.append('')
|
||||
|
||||
OUT.write_text('\n'.join(out_lines), encoding='utf-8')
|
||||
print(f'Wrote {OUT}')
|
||||
print(f'Bytes: {OUT.stat().st_size}')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,166 @@
|
||||
# ============================================================================
|
||||
# Synology Permission Discovery via DSM API - cascadesDS (192.168.0.120)
|
||||
# ----------------------------------------------------------------------------
|
||||
# Runs on CS-SERVER via GuruRMM. Uses DSM's HTTP API (port 5000) instead of
|
||||
# SSH since SSH is not enabled on this Synology.
|
||||
#
|
||||
# Strictly read-only. Login -> list users/groups/shares -> per-share
|
||||
# permissions -> logout.
|
||||
#
|
||||
# Prepared: 2026-04-22 (Cascades Phase 4 Synology retirement prep)
|
||||
# ============================================================================
|
||||
|
||||
$ErrorActionPreference = 'Continue'
|
||||
$SynoBase = 'http://192.168.0.120:5000'
|
||||
$SynoUser = 'admin'
|
||||
$SynoPass = '__SYNO_PASSWORD__'
|
||||
|
||||
function Section($n) {
|
||||
Write-Output ''
|
||||
Write-Output ('=' * 72)
|
||||
Write-Output "== $n"
|
||||
Write-Output ('=' * 72)
|
||||
}
|
||||
|
||||
function Dump($label, $obj) {
|
||||
Write-Output ''
|
||||
Write-Output "--- $label ---"
|
||||
try {
|
||||
$obj | ConvertTo-Json -Depth 8 | Write-Output
|
||||
} catch {
|
||||
$obj | Format-List * | Out-String | Write-Output
|
||||
}
|
||||
}
|
||||
|
||||
# TLS changes queued for tonight but not yet effective (reboot @ 18:00). This
|
||||
# talks HTTP port 5000 so TLS state doesn't matter here.
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
Section 'Step 0: API version discovery'
|
||||
# ----------------------------------------------------------------------------
|
||||
try {
|
||||
$info = Invoke-RestMethod -Uri "$SynoBase/webapi/query.cgi?api=SYNO.API.Info&version=1&method=query&query=SYNO.API.Auth,SYNO.Core.User,SYNO.Core.Group,SYNO.Core.Share,SYNO.Core.Share.Permission,SYNO.Core.Group.Member"
|
||||
Dump 'SYNO.API.Info' $info
|
||||
} catch {
|
||||
Write-Output "API info probe failed: $_"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Derive authenticate path + max version
|
||||
$authPath = $info.data.'SYNO.API.Auth'.path
|
||||
$authMax = $info.data.'SYNO.API.Auth'.maxVersion
|
||||
Write-Output "auth path: $authPath, maxVersion: $authMax"
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
Section 'Step 1: Login'
|
||||
# ----------------------------------------------------------------------------
|
||||
$loginUri = "$SynoBase/webapi/$authPath" +
|
||||
"?api=SYNO.API.Auth&version=$authMax&method=login" +
|
||||
"&account=$([uri]::EscapeDataString($SynoUser))" +
|
||||
"&passwd=$([uri]::EscapeDataString($SynoPass))" +
|
||||
"&session=FileStation&format=sid"
|
||||
try {
|
||||
$loginResp = Invoke-RestMethod -Uri $loginUri
|
||||
Dump 'login response' $loginResp
|
||||
if (-not $loginResp.success) {
|
||||
Write-Output "LOGIN FAILED: $($loginResp | ConvertTo-Json -Depth 5)"
|
||||
exit 1
|
||||
}
|
||||
$sid = $loginResp.data.sid
|
||||
Write-Output "sid: $sid"
|
||||
} catch {
|
||||
Write-Output "Login exception: $_"
|
||||
exit 1
|
||||
}
|
||||
|
||||
try {
|
||||
# ------------------------------------------------------------------------
|
||||
Section 'Step 2: Users'
|
||||
# ------------------------------------------------------------------------
|
||||
# SYNO.Core.User list with all additional fields
|
||||
$userResp = Invoke-RestMethod -Uri ("$SynoBase/webapi/entry.cgi?api=SYNO.Core.User&version=1&method=list" +
|
||||
"&offset=0&limit=500&type=local" +
|
||||
"&additional=%5B%22email%22%2C%22description%22%2C%22expired%22%2C%22cannot_chg_passwd%22%2C%22passwd_never_expire%22%2C%22passwd_last_change%22%2C%22passwd_must_change%22%2C%22groups%22%5D" +
|
||||
"&_sid=$sid")
|
||||
Dump 'SYNO.Core.User list' $userResp
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
Section 'Step 3: Groups'
|
||||
# ------------------------------------------------------------------------
|
||||
$groupResp = Invoke-RestMethod -Uri ("$SynoBase/webapi/entry.cgi?api=SYNO.Core.Group&version=1&method=list" +
|
||||
"&offset=0&limit=500&type=local" +
|
||||
"&additional=%5B%22description%22%2C%22group_type%22%2C%22members%22%5D" +
|
||||
"&_sid=$sid")
|
||||
Dump 'SYNO.Core.Group list' $groupResp
|
||||
|
||||
# Group members (separate call in some DSM versions)
|
||||
$groups = $groupResp.data.groups
|
||||
foreach ($g in $groups) {
|
||||
try {
|
||||
$memResp = Invoke-RestMethod -Uri ("$SynoBase/webapi/entry.cgi?api=SYNO.Core.Group.Member&version=1&method=list" +
|
||||
"&group_name=$([uri]::EscapeDataString($g.name))" +
|
||||
"&offset=0&limit=500&_sid=$sid")
|
||||
Dump "members of group '$($g.name)'" $memResp
|
||||
} catch {
|
||||
Write-Output "Group member lookup for '$($g.name)' failed: $_"
|
||||
}
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
Section 'Step 4: Shares'
|
||||
# ------------------------------------------------------------------------
|
||||
$shareResp = Invoke-RestMethod -Uri ("$SynoBase/webapi/entry.cgi?api=SYNO.Core.Share&version=1&method=list" +
|
||||
"&shareType=all&offset=0&limit=200" +
|
||||
"&additional=%5B%22hidden%22%2C%22encryption%22%2C%22share_quota%22%2C%22recyclebin%22%2C%22enable_share_cow%22%2C%22enable_share_compress%22%2C%22name%22%2C%22vol_path%22%2C%22desc%22%5D" +
|
||||
"&_sid=$sid")
|
||||
Dump 'SYNO.Core.Share list' $shareResp
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
Section 'Step 5: Per-share permissions'
|
||||
# ------------------------------------------------------------------------
|
||||
$shares = $shareResp.data.shares
|
||||
foreach ($sh in $shares) {
|
||||
try {
|
||||
# Permissions by user
|
||||
$permUser = Invoke-RestMethod -Uri ("$SynoBase/webapi/entry.cgi?api=SYNO.Core.Share.Permission&version=1&method=list" +
|
||||
"&name=$([uri]::EscapeDataString($sh.name))" +
|
||||
"&user_group_type=local_user&offset=0&limit=500" +
|
||||
"&_sid=$sid")
|
||||
Dump "share '$($sh.name)' - local user permissions" $permUser
|
||||
# Permissions by group
|
||||
$permGroup = Invoke-RestMethod -Uri ("$SynoBase/webapi/entry.cgi?api=SYNO.Core.Share.Permission&version=1&method=list" +
|
||||
"&name=$([uri]::EscapeDataString($sh.name))" +
|
||||
"&user_group_type=local_group&offset=0&limit=500" +
|
||||
"&_sid=$sid")
|
||||
Dump "share '$($sh.name)' - local group permissions" $permGroup
|
||||
} catch {
|
||||
Write-Output "Permission lookup for '$($sh.name)' failed: $_"
|
||||
}
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
Section 'Step 6: SMB share config (supplementary)'
|
||||
# ------------------------------------------------------------------------
|
||||
# SMB exposure state per share via FileService.SMB.Share or similar
|
||||
try {
|
||||
$smb = Invoke-RestMethod -Uri "$SynoBase/webapi/entry.cgi?api=SYNO.Core.FileServ.SMB&version=1&method=get&_sid=$sid"
|
||||
Dump 'SMB service config' $smb
|
||||
} catch {
|
||||
Write-Output "SMB service config lookup failed: $_"
|
||||
}
|
||||
|
||||
} finally {
|
||||
# ------------------------------------------------------------------------
|
||||
Section 'Logout'
|
||||
# ------------------------------------------------------------------------
|
||||
try {
|
||||
$logout = Invoke-RestMethod -Uri "$SynoBase/webapi/$authPath?api=SYNO.API.Auth&version=$authMax&method=logout&session=FileStation&_sid=$sid"
|
||||
Dump 'logout' $logout
|
||||
} catch {
|
||||
Write-Output "Logout failed: $_"
|
||||
}
|
||||
}
|
||||
|
||||
Section 'Done'
|
||||
Write-Output "Completed at $(Get-Date)"
|
||||
@@ -0,0 +1,132 @@
|
||||
# ============================================================================
|
||||
# Synology Permission Discovery - cascadesDS (192.168.0.120)
|
||||
# ----------------------------------------------------------------------------
|
||||
# Runs on CS-SERVER via GuruRMM. Uses plink.exe (PuTTY) to SSH into the
|
||||
# Synology and dump users, groups, share ACLs, and SMB share configs.
|
||||
#
|
||||
# Strictly read-only. No writes, no creates, no config changes.
|
||||
# Output is captured and printed to stdout for the RMM command to return.
|
||||
#
|
||||
# Prepared: 2026-04-22 (Cascades Phase 4 Synology retirement prep)
|
||||
# ============================================================================
|
||||
|
||||
$ErrorActionPreference = 'Continue'
|
||||
$SynoHost = '192.168.0.120'
|
||||
$SynoUser = 'admin'
|
||||
# Password injected via command substitution at execution time.
|
||||
# Do NOT hardcode here - see the submission wrapper.
|
||||
$SynoPass = '__SYNO_PASSWORD__'
|
||||
|
||||
function Section($n) {
|
||||
Write-Output ''
|
||||
Write-Output ('=' * 72)
|
||||
Write-Output "== $n"
|
||||
Write-Output ('=' * 72)
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
Section 'Step 1: Connectivity'
|
||||
# ----------------------------------------------------------------------------
|
||||
$reach = Test-NetConnection -ComputerName $SynoHost -Port 22 -InformationLevel Detailed -WarningAction SilentlyContinue
|
||||
Write-Output "SSH 192.168.0.120:22 reachable: $($reach.TcpTestSucceeded)"
|
||||
if (-not $reach.TcpTestSucceeded) {
|
||||
Write-Output 'ABORT: Cannot reach Synology over SSH. Check pfSense rules + Synology service state.'
|
||||
exit 1
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
Section 'Step 2: Locate plink.exe'
|
||||
# ----------------------------------------------------------------------------
|
||||
$plink = $null
|
||||
$candidates = @(
|
||||
'C:\Program Files\PuTTY\plink.exe',
|
||||
'C:\Program Files (x86)\PuTTY\plink.exe',
|
||||
'C:\Tools\plink.exe'
|
||||
)
|
||||
foreach ($c in $candidates) { if (Test-Path $c) { $plink = $c; break } }
|
||||
if (-not $plink) {
|
||||
$plink = (Get-Command plink.exe -ErrorAction SilentlyContinue | Select-Object -First 1).Source
|
||||
}
|
||||
if (-not $plink) {
|
||||
Write-Output 'ABORT: plink.exe not found. Install PuTTY or point at a plink.exe path.'
|
||||
exit 1
|
||||
}
|
||||
Write-Output "plink.exe: $plink"
|
||||
$plinkVer = & $plink -V 2>&1 | Select-Object -First 1
|
||||
Write-Output "plink version: $plinkVer"
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
Section 'Step 3: Pre-accept SSH host key (first run)'
|
||||
# ----------------------------------------------------------------------------
|
||||
# plink with -batch refuses unknown host keys. Pre-accept by piping 'y' into a
|
||||
# non-batch run that does a harmless probe. Subsequent calls use -batch.
|
||||
$preaccept = 'y' | & $plink -ssh -pw $SynoPass "$SynoUser@$SynoHost" 'echo preaccept-ok' 2>&1
|
||||
Write-Output ($preaccept -join "`n")
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
Section 'Step 4: Synology probe - identity + shares + ACLs'
|
||||
# ----------------------------------------------------------------------------
|
||||
# Single heredoc-style payload: one SSH session, captures everything.
|
||||
# synogroup/synouser/synoacltool/synoshare often need sudo on DSM 7; admin is
|
||||
# in administrators group but sudo may still prompt. Use 'sudo -S' with the
|
||||
# password piped via echo to handle the prompt gracefully.
|
||||
$probe = @'
|
||||
PASS="__SUDO_PASSWORD__"
|
||||
sudo_run() { echo "$PASS" | sudo -S -p '' "$@" 2>&1; }
|
||||
|
||||
echo "### date ###"
|
||||
date
|
||||
echo
|
||||
echo "### dsm version ###"
|
||||
cat /etc.defaults/VERSION 2>&1 || cat /etc/VERSION 2>&1
|
||||
echo
|
||||
echo "### synogroup --list ###"
|
||||
sudo_run synogroup --list
|
||||
echo
|
||||
echo "### synogroup --enum global ###"
|
||||
sudo_run synogroup --enum global
|
||||
echo
|
||||
echo "### synouser --enum all ###"
|
||||
sudo_run synouser --enum all
|
||||
echo
|
||||
echo "### /volume1/ directory listing ###"
|
||||
ls -la /volume1/ 2>&1
|
||||
echo
|
||||
echo "### /etc/samba/smb.share.conf ###"
|
||||
sudo_run cat /etc/samba/smb.share.conf 2>&1 | head -200
|
||||
echo
|
||||
echo "### synoshare --enum all ###"
|
||||
sudo_run synoshare --enum all
|
||||
echo
|
||||
for S in homes Management SalesDept Server chat Public Culinary IT Receptionist directoryshare Marketing; do
|
||||
if [ -d /volume1/$S ]; then
|
||||
echo "### synoshare --get $S ###"
|
||||
sudo_run synoshare --get "$S"
|
||||
echo
|
||||
echo "### synoacltool -get /volume1/$S ###"
|
||||
sudo_run synoacltool -get "/volume1/$S"
|
||||
echo
|
||||
echo "### ls -la /volume1/$S (first 15 entries) ###"
|
||||
ls -la "/volume1/$S" 2>&1 | head -15
|
||||
echo
|
||||
fi
|
||||
done
|
||||
echo "### NET SESSIONS / SMB share access (smbstatus) ###"
|
||||
sudo_run smbstatus -p 2>&1 | head -20
|
||||
echo
|
||||
echo "### EOF ###"
|
||||
'@
|
||||
|
||||
# Splice in the sudo password (same as SSH password for admin account)
|
||||
$probe = $probe -replace '__SUDO_PASSWORD__', [regex]::Escape($SynoPass) -replace '\\/','/'
|
||||
# Proper way: use literal replacement without regex escape tricks
|
||||
$probe = $probe.Replace('__SUDO_PASSWORD__', $SynoPass)
|
||||
|
||||
# Execute via plink; batch mode since host key is now cached
|
||||
$result = $probe | & $plink -ssh -batch -pw $SynoPass "$SynoUser@$SynoHost" 'bash -s' 2>&1
|
||||
$result | ForEach-Object { Write-Output $_ }
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
Section 'Done'
|
||||
# ----------------------------------------------------------------------------
|
||||
Write-Output "Completed at $(Get-Date)"
|
||||
@@ -0,0 +1,132 @@
|
||||
# Synology cascadesDS — Analysis + Migration Mapping (2026-04-22)
|
||||
|
||||
**Inventory source:** `synology-permission-inventory.md` (derived from `synology-permission-inventory-raw.md`)
|
||||
**Purpose:** Feed the Phase 4 (`phase4-synology.md` §6.0) permission migration — CS-SERVER NTFS/SMB applied via `scripts/phase2-file-shares.ps1`.
|
||||
|
||||
---
|
||||
|
||||
## Headline observations
|
||||
|
||||
### 1. Shared-account / role-based logins exist on Synology
|
||||
The following Synology user accounts are **role names, not individuals**. Each is a HIPAA §164.312(a)(2)(i) Unique User Identification problem on the Synology — multiple humans sharing one credential when accessing PHI-bearing shares:
|
||||
|
||||
- `Accounting`
|
||||
- `Dining Manager`
|
||||
- `Front Desk`
|
||||
- `mcnurse` (Memory Care nurse)
|
||||
- `Memcare Receptionist`
|
||||
- `memcarenurse`
|
||||
- `Nurse Tower`
|
||||
|
||||
These should **not** be carried forward to CS-SERVER. The CS-SERVER model is per-person named accounts (already Howard's 2026-04-22 rollout plan), so at cutover these shared logins disappear and their previously-assigned permissions migrate to the appropriate AD security group.
|
||||
|
||||
### 2. Departed employees still present on Synology
|
||||
Per our AD state and the 2026-04-22 working list:
|
||||
|
||||
| Synology user | Status |
|
||||
|---|---|
|
||||
| `Amber M Lee` | Not in AD or current roster — treat as departed |
|
||||
| `Ann Dery` | Former employee (deleted from AD 2026-04-13) |
|
||||
| `Anna Pitzlin` | Former employee (confirmed by HR, slated for deletion) |
|
||||
| `Britney Thompson` | Departed 2026-04-22 per John's reply |
|
||||
| `Haris Durut` | Former employee (deleted from AD 2026-04-13) |
|
||||
| `Monica RamirezRossette` | Former employee (removed from Domain Admins 2026-03-09) |
|
||||
| `Nela Durut-Azizi` | Former employee (already expired=yes on Synology) |
|
||||
| `Tamra Johnson` | Renamed to `Tamra Matthews`; the Synology account is the old name |
|
||||
|
||||
None of these carry forward. Delete after cutover.
|
||||
|
||||
### 3. Service/admin accounts to keep or retire
|
||||
|
||||
| Account | Keep or retire |
|
||||
|---|---|
|
||||
| `admin` | Keep (DSM default; locked to administrators). Used only during maintenance. |
|
||||
| `guest` | Already expired=yes. Leave disabled. HIPAA audit says remove; keep as-is for now. |
|
||||
| `guru` | Keep (MSP / Computer Guru service account). Rotate password post-cutover. |
|
||||
| `CasAdmin201` | **Investigate** — looks like a prior-MSP admin account. Has Admin rights on every share. Recommend disable + confirm with Meredith before deletion. |
|
||||
| `VPNClient` | Synology VPN service account; narrow purpose. Keep as-is unless VPN feature is retired. |
|
||||
|
||||
### 4. Four Synology groups, but only one is load-bearing for staff
|
||||
- `administrators` — DSM admin group. Full control everywhere.
|
||||
- `http` — Web-service group, not staff-facing.
|
||||
- `MainOffice` — Appears to be a custom group for office staff. **This is the one we need to translate into AD groups** when migrating share access.
|
||||
- `users` — Default membership (every local user is a member). Most share permissions grant modest rights to this group.
|
||||
|
||||
Group-member enumeration via the DSM API returned error 3201; full membership will need to be captured via DSM web UI (Control Panel → User & Group → Group → double-click → Members tab) or via CLI when SSH is enabled.
|
||||
|
||||
### 5. Sandra Fish share
|
||||
There's a share named `Sandra Fish` — former director's personal folder. Has the same deny pattern as other shares. **Decision needed:** archive contents to `Archive\Former-Director-Sandra-Fish\` on CS-SERVER and delete the share, or keep accessible only to Meredith as custodian until retention expires (state/HIPAA).
|
||||
|
||||
### 6. pacs share
|
||||
`pacs` likely refers to a Picture Archiving and Communication System — medical imaging. Heavy deny pattern (most users denied by default). This is a **HIPAA-clinical share**. Worth confirming with Meredith what's actually in it before moving — if it's live imaging of residents, EncryptData is mandatory and access should narrow to Clinical-PHI group.
|
||||
|
||||
### 7. `web`, `Activities`, `chat` shares
|
||||
- `web` — likely the DSM Web Station share. Mostly denied for users. Retire with Synology.
|
||||
- `Activities` — Life Enrichment activity docs? Unclear. Meredith-confirm.
|
||||
- `chat` — likely for DSM Chat. If unused (Teams is the planned chat per HIPAA doc), retire.
|
||||
|
||||
---
|
||||
|
||||
## Synology → AD identity mapping
|
||||
|
||||
For the 2026-04-22 active roster, here is the proposed mapping. Use this to feed `SG-*` group memberships before `phase2-file-shares.ps1` runs.
|
||||
|
||||
| Synology user | AD identity (SamAccountName) | AD department |
|
||||
|---|---|---|
|
||||
| `Ashley Jensen` | `Ashley.Jensen` | Administrative |
|
||||
| `ChristinaDupras` | `Christina.DuPras` | Resident Services |
|
||||
| `Crystal Rodriguez` | `Crystal.Rodriguez` | Marketing |
|
||||
| `Crystal Suszek` | *(alias of Crystal Rodriguez — consolidate; no second AD account)* | — |
|
||||
| `JD Martin` | `JD.Martin` | Culinary |
|
||||
| `John Trozzi` | `John.Trozzi` | Maintenance |
|
||||
| `Karen Rossini` | `karen.rossini` | Care, Assisted Living |
|
||||
| `Lois Lane` | `Lois.Lane` | Care, Assisted Living |
|
||||
| `Lupe Sanchez` | `Lupe.Sanchez` | Housekeeping |
|
||||
| `Megan Hiatt` | `Megan.Hiatt` | Marketing |
|
||||
| `meredith kuhn` | `Meredith.Kuhn` | Administrative |
|
||||
| `Shelby Trozzi` | `Shelby.Trozzi` | Memory Care |
|
||||
| `Susan Hicks` | `Susan.Hicks` | Life Enrichment |
|
||||
| `Veronica` | `Veronica.Feller` | Care, Assisted Living |
|
||||
| `Stephanie Devin` | *(not in AD — blocked in M365, former employee)* | — |
|
||||
|
||||
Not migrated: Amber M Lee, Ann Dery, Anna Pitzlin, Britney Thompson, Haris Durut, Monica RamirezRossette, Nela Durut-Azizi, Tamra Johnson. Plus all role accounts in observation #1.
|
||||
|
||||
---
|
||||
|
||||
## Proposed AD security group → CS-SERVER share mapping
|
||||
|
||||
Mirror of the Synology pattern, collapsed onto the AD security groups we're creating in the rollout (see `docs/cloud/user-account-rollout-plan.md` §4). Individual user ACEs from Synology merge into the matching group.
|
||||
|
||||
| Share | Who gets RW on CS-SERVER | Who gets RO | Notes |
|
||||
|---|---|---|---|
|
||||
| `Management` | `SG-Management-RW` = Administrative + Sales Director + Clinical Directors + Life Enrichment Director | Authenticated Users (RO) | Current Synology: deny-by-default, individual grants; clean slate on CS-SERVER with group-based |
|
||||
| `SalesDept` | `SG-Sales-RW` = Megan, Crystal, Tamra, Lauren, Allison, Ashley | — | PHI concern (resident intake forms) — audit SACL required |
|
||||
| `Server` | `SG-Server-RW` = Administrative + IT | — | IT / sysadmin scratch space |
|
||||
| `homes` | Per-user only (`CREATOR OWNER` for new subfolders, `Domain Users` read on root) | — | Already the CS-SERVER pattern per `phase2-server-prep.md` |
|
||||
| `Public` | `Authenticated Users` RW | — | Non-sensitive shared area |
|
||||
| `Culinary` | `SG-Culinary-RW` = JD Martin, Ramon, Alyssa | — | Already created on CS-SERVER (per `cs-server.md` §SMB shares) — verify ACL |
|
||||
| `pacs` | **INVESTIGATE FIRST** — clinical imaging; scope to `SG-Clinical-PHI` if confirmed + enable SMB3 encryption + SACL auditing | — | Critical PHI share; do not migrate until confirmed |
|
||||
| `Activities` | TBD — ask Meredith | TBD | Life Enrichment? |
|
||||
| `chat`, `web` | Do not migrate | — | Retire with Synology |
|
||||
| `Sandra Fish` | Archive-only access for Meredith + IT | — | Former-director data; retention decision needed |
|
||||
|
||||
---
|
||||
|
||||
## Questions for Meredith / Howard before cutover
|
||||
|
||||
1. What is in `pacs` today? If it's medical imaging, we treat it as the highest-sensitivity share — strict ACL, SMB3 encryption, full Object Access audit SACL, dedicated `SG-Clinical-PHI` group.
|
||||
2. What is in `Activities`? Life Enrichment docs? HIPAA-relevant (resident participation records)?
|
||||
3. `CasAdmin201` — who is/was this? Used today or legacy?
|
||||
4. Is Meredith's `Sandra Fish` share something to archive long-term or purge?
|
||||
5. `chat` — currently used? If not, confirm for retirement.
|
||||
|
||||
---
|
||||
|
||||
## Next action items
|
||||
|
||||
- [ ] Walk through DSM Control Panel with Howard to capture the `MainOffice` group membership (API error 3201 blocked automated pull)
|
||||
- [ ] Confirm with Meredith the content/use of `pacs`, `Activities`, `chat`, `Sandra Fish`
|
||||
- [ ] Update `docs/migration/scripts/phase2-file-shares.ps1` inputs with the mapping table above
|
||||
- [ ] After CS-SERVER is migrated: disable Synology shared-account logins (`Accounting`, `Front Desk`, `mcnurse`, `memcarenurse`, `Memcare Receptionist`, `Nurse Tower`, `Dining Manager`) — HIPAA compliance cleanup
|
||||
- [ ] After CS-SERVER is migrated: disable former-employee Synology accounts (Amber, Ann, Anna, Britney, Haris, Monica, Nela, Tamra)
|
||||
- [ ] Reconfigure Synology as backup target per `phase4-synology.md` §6.4, retire it as a NAS
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,488 @@
|
||||
# Synology cascadesDS — Permission Inventory (2026-04-22 via DSM API)
|
||||
|
||||
**Source:** `docs/migration/synology-permission-inventory-raw.md`
|
||||
**Method:** DSM HTTP API v7 via CS-SERVER GuruRMM agent (SSH not enabled on Synology as of 2026-04-22)
|
||||
|
||||
## Summary counts
|
||||
|
||||
- Synology local users: **35**
|
||||
- Synology local groups: **4**
|
||||
- Shares: **10**
|
||||
|
||||
## Users
|
||||
|
||||
| Name | UID | Expired | Email | Description | Groups |
|
||||
|---|---:|---|---|---|---|
|
||||
| `Accounting` | - | no | | | - |
|
||||
| `admin` | - | no | | System default user | - |
|
||||
| `Amber M Lee` | - | no | | | - |
|
||||
| `Ann Dery` | - | no | | | - |
|
||||
| `Anna Pitzlin` | - | no | anna.pitzlin@cascadestucson.com | | - |
|
||||
| `Ashley Jensen` | - | no | ashley.jensen@cascadestucson.com | | - |
|
||||
| `Britney Thompson` | - | no | Britney.Thompson@cascadestucson.com | | - |
|
||||
| `CasAdmin201` | - | no | | | - |
|
||||
| `ChristinaDupras` | - | no | | | - |
|
||||
| `Crystal Rodriguez` | - | no | Crystal.rodriguez@cascadestucson.com | | - |
|
||||
| `Crystal Suszek` | - | no | crystal.suszek@cascadestucson.com | | - |
|
||||
| `Dining Manager` | - | no | | | - |
|
||||
| `Front Desk` | - | no | | | - |
|
||||
| `guest` | - | yes | | Guest | - |
|
||||
| `guru` | - | no | | | - |
|
||||
| `Haris Durut` | - | no | haris.durut@cascadestucson.com | | - |
|
||||
| `JD Martin` | - | no | jd.martin@cascadestucson.com | | - |
|
||||
| `John Trozzi` | - | no | | | - |
|
||||
| `Karen Rossini` | - | no | karen.rossini@cascadestucson.com | | - |
|
||||
| `Lois Lane` | - | no | | | - |
|
||||
| `Lupe Sanchez` | - | no | | | - |
|
||||
| `mcnurse` | - | no | | | - |
|
||||
| `Megan Hiatt` | - | no | | | - |
|
||||
| `Memcare Receptionist` | - | no | memcarereceptionist@cascadestucson.com | | - |
|
||||
| `memcarenurse` | - | no | memcarenurse@cascadestucson.com | | - |
|
||||
| `meredith kuhn` | - | no | meredith.kuhn@cascadestucson.com | | - |
|
||||
| `Monica RamirezRossette` | - | no | accounting@cascadestucson.com | | - |
|
||||
| `Nela Durut-Azizi` | - | yes | nela.durut-azizi@cascadestucson.com | | - |
|
||||
| `Nurse Tower` | - | no | | | - |
|
||||
| `Shelby Trozzi` | - | no | shelby.trozzi@cascadestucson.com | | - |
|
||||
| `Stephanie Devin` | - | no | Stephanie.devin@cascadestucson.com | Accounting Assist | - |
|
||||
| `Susan Hicks` | - | no | | | - |
|
||||
| `Tamra Johnson` | - | no | tamra.johnson@cascadestucson.com | | - |
|
||||
| `Veronica` | - | no | | | - |
|
||||
| `VPNClient` | - | no | | | - |
|
||||
|
||||
## Groups
|
||||
|
||||
| Name | GID | Type | Description | Members |
|
||||
|---|---:|---|---|---|
|
||||
| `administrators` | - | - | | (unable to enumerate via API — error 3201) |
|
||||
| `http` | - | - | | (unable to enumerate via API — error 3201) |
|
||||
| `MainOffice` | - | - | | (unable to enumerate via API — error 3201) |
|
||||
| `users` | - | - | | (unable to enumerate via API — error 3201) |
|
||||
|
||||
> Note: DSM API `SYNO.Core.Group.Member` returned error 3201 for all groups with this API path; membership was only partially available via the `members` additional field on the group list call. Full membership requires DSM web UI or CLI `synogroup --get <name>` via SSH.
|
||||
|
||||
## Shares
|
||||
|
||||
| Share | Volume Path | Hidden | Description |
|
||||
|---|---|---|---|
|
||||
| `Activities` | /volume1 | False | |
|
||||
| `chat` | /volume1 | False | |
|
||||
| `homes` | /volume1 | False | |
|
||||
| `Management` | /volume1 | False | |
|
||||
| `pacs` | /volume1 | False | |
|
||||
| `Public` | /volume1 | False | |
|
||||
| `SalesDept` | /volume1 | False | |
|
||||
| `Sandra Fish` | /volume1 | False | |
|
||||
| `Server` | /volume1 | False | |
|
||||
| `web` | /volume1 | False | |
|
||||
|
||||
## Effective share permissions
|
||||
|
||||
"Admin(full)" means the account inherits full control via administrators-group membership. "RW" means explicitly writable. "DENY" means explicitly denied (wins over everything else in Synology ACL order). Blank / absent means no explicit permission (effectively no access beyond what the users group grants).
|
||||
|
||||
### Share: `Activities`
|
||||
|
||||
**Groups:**
|
||||
|
||||
| Group | Effective |
|
||||
|---|---|
|
||||
| `MainOffice` | DENY |
|
||||
| `administrators` | Admin(full) |
|
||||
| `http` | - |
|
||||
| `users` | RW |
|
||||
|
||||
**Users with explicit permission:**
|
||||
|
||||
| User | Effective | Status |
|
||||
|---|---|---|
|
||||
| `Accounting` | DENY | ROLE (HIPAA concern) |
|
||||
| `admin` | RW | service/admin |
|
||||
| `Ann Dery` | DENY | DEPARTED |
|
||||
| `Anna Pitzlin` | DENY | DEPARTED |
|
||||
| `Ashley Jensen` | RW | current |
|
||||
| `Britney Thompson` | RW | DEPARTED |
|
||||
| `CasAdmin201` | RW | current |
|
||||
| `ChristinaDupras` | DENY | current |
|
||||
| `Crystal Rodriguez` | DENY | current |
|
||||
| `Crystal Suszek` | DENY | current |
|
||||
| `Dining Manager` | DENY | ROLE (HIPAA concern) |
|
||||
| `Front Desk` | DENY | ROLE (HIPAA concern) |
|
||||
| `guest` | DENY | service/admin |
|
||||
| `guru` | RW | service/admin |
|
||||
| `Haris Durut` | DENY | DEPARTED |
|
||||
| `JD Martin` | DENY | current |
|
||||
| `John Trozzi` | DENY | current |
|
||||
| `Karen Rossini` | DENY | current |
|
||||
| `Lois Lane` | DENY | current |
|
||||
| `Lupe Sanchez` | DENY | current |
|
||||
| `mcnurse` | DENY | ROLE (HIPAA concern) |
|
||||
| `Megan Hiatt` | DENY | current |
|
||||
| `Memcare Receptionist` | DENY | ROLE (HIPAA concern) |
|
||||
| `memcarenurse` | DENY | ROLE (HIPAA concern) |
|
||||
| `meredith kuhn` | DENY | current |
|
||||
| `Nela Durut-Azizi` | DENY | DEPARTED |
|
||||
| `Nurse Tower` | DENY | ROLE (HIPAA concern) |
|
||||
| `Shelby Trozzi` | DENY | current |
|
||||
| `Stephanie Devin` | RW | current |
|
||||
| `Susan Hicks` | DENY | current |
|
||||
| `Tamra Johnson` | DENY | DEPARTED |
|
||||
| `Veronica` | RW | current |
|
||||
| `VPNClient` | DENY | service/admin |
|
||||
|
||||
### Share: `Management`
|
||||
|
||||
**Groups:**
|
||||
|
||||
| Group | Effective |
|
||||
|---|---|
|
||||
| `MainOffice` | - |
|
||||
| `administrators` | RW |
|
||||
| `http` | - |
|
||||
| `users` | - |
|
||||
|
||||
**Users with explicit permission:**
|
||||
|
||||
| User | Effective | Status |
|
||||
|---|---|---|
|
||||
| `Accounting` | RW | ROLE (HIPAA concern) |
|
||||
| `admin` | RW | service/admin |
|
||||
| `Ashley Jensen` | RW | current |
|
||||
| `Britney Thompson` | RW | DEPARTED |
|
||||
| `CasAdmin201` | RW | current |
|
||||
| `Crystal Rodriguez` | RW | current |
|
||||
| `Crystal Suszek` | RW | current |
|
||||
| `guru` | RW | service/admin |
|
||||
| `Lois Lane` | DENY | current |
|
||||
| `Megan Hiatt` | RW | current |
|
||||
| `meredith kuhn` | RW | current |
|
||||
| `Shelby Trozzi` | RW | current |
|
||||
| `Stephanie Devin` | RW | current |
|
||||
| `Tamra Johnson` | RW | DEPARTED |
|
||||
| `Veronica` | RW | current |
|
||||
|
||||
### Share: `Public`
|
||||
|
||||
**Groups:**
|
||||
|
||||
| Group | Effective |
|
||||
|---|---|
|
||||
| `MainOffice` | DENY |
|
||||
| `administrators` | RW |
|
||||
| `http` | - |
|
||||
| `users` | RW |
|
||||
|
||||
**Users with explicit permission:**
|
||||
|
||||
| User | Effective | Status |
|
||||
|---|---|---|
|
||||
| `Accounting` | RW | ROLE (HIPAA concern) |
|
||||
| `admin` | RW | service/admin |
|
||||
| `Amber M Lee` | RW | DEPARTED |
|
||||
| `Ann Dery` | RW | DEPARTED |
|
||||
| `Ashley Jensen` | RW | current |
|
||||
| `Britney Thompson` | RW | DEPARTED |
|
||||
| `CasAdmin201` | RW | current |
|
||||
| `ChristinaDupras` | RW | current |
|
||||
| `guru` | RW | service/admin |
|
||||
| `JD Martin` | RW | current |
|
||||
| `Karen Rossini` | DENY | current |
|
||||
| `meredith kuhn` | Admin(full) | current |
|
||||
| `Shelby Trozzi` | Admin(full) | current |
|
||||
| `Stephanie Devin` | RW | current |
|
||||
| `Veronica` | RW | current |
|
||||
|
||||
### Share: `SalesDept`
|
||||
|
||||
**Groups:**
|
||||
|
||||
| Group | Effective |
|
||||
|---|---|
|
||||
| `MainOffice` | DENY |
|
||||
| `administrators` | Admin(full) |
|
||||
| `http` | - |
|
||||
| `users` | RW |
|
||||
|
||||
**Users with explicit permission:**
|
||||
|
||||
| User | Effective | Status |
|
||||
|---|---|---|
|
||||
| `admin` | RW | service/admin |
|
||||
| `Ann Dery` | DENY | DEPARTED |
|
||||
| `Anna Pitzlin` | DENY | DEPARTED |
|
||||
| `Ashley Jensen` | RW | current |
|
||||
| `Britney Thompson` | RW | DEPARTED |
|
||||
| `CasAdmin201` | RW | current |
|
||||
| `ChristinaDupras` | DENY | current |
|
||||
| `Dining Manager` | DENY | ROLE (HIPAA concern) |
|
||||
| `Front Desk` | DENY | ROLE (HIPAA concern) |
|
||||
| `guru` | RW | service/admin |
|
||||
| `Haris Durut` | DENY | DEPARTED |
|
||||
| `JD Martin` | DENY | current |
|
||||
| `John Trozzi` | DENY | current |
|
||||
| `Karen Rossini` | DENY | current |
|
||||
| `Lois Lane` | DENY | current |
|
||||
| `Lupe Sanchez` | DENY | current |
|
||||
| `mcnurse` | DENY | ROLE (HIPAA concern) |
|
||||
| `Megan Hiatt` | RW | current |
|
||||
| `Memcare Receptionist` | DENY | ROLE (HIPAA concern) |
|
||||
| `memcarenurse` | DENY | ROLE (HIPAA concern) |
|
||||
| `meredith kuhn` | Admin(full) | current |
|
||||
| `Nela Durut-Azizi` | DENY | DEPARTED |
|
||||
| `Nurse Tower` | DENY | ROLE (HIPAA concern) |
|
||||
| `Shelby Trozzi` | Admin(full) | current |
|
||||
| `Veronica` | RW | current |
|
||||
|
||||
### Share: `Sandra Fish`
|
||||
|
||||
**Groups:**
|
||||
|
||||
| Group | Effective |
|
||||
|---|---|
|
||||
| `MainOffice` | DENY |
|
||||
| `administrators` | Admin(full) |
|
||||
| `http` | - |
|
||||
| `users` | - |
|
||||
|
||||
**Users with explicit permission:**
|
||||
|
||||
| User | Effective | Status |
|
||||
|---|---|---|
|
||||
| `Accounting` | DENY | ROLE (HIPAA concern) |
|
||||
| `admin` | RW | service/admin |
|
||||
| `Ann Dery` | DENY | DEPARTED |
|
||||
| `Anna Pitzlin` | DENY | DEPARTED |
|
||||
| `Ashley Jensen` | RW | current |
|
||||
| `Britney Thompson` | RW | DEPARTED |
|
||||
| `CasAdmin201` | RW | current |
|
||||
| `ChristinaDupras` | DENY | current |
|
||||
| `Crystal Rodriguez` | DENY | current |
|
||||
| `Crystal Suszek` | DENY | current |
|
||||
| `Dining Manager` | DENY | ROLE (HIPAA concern) |
|
||||
| `Front Desk` | DENY | ROLE (HIPAA concern) |
|
||||
| `guest` | DENY | service/admin |
|
||||
| `guru` | RW | service/admin |
|
||||
| `Haris Durut` | DENY | DEPARTED |
|
||||
| `JD Martin` | DENY | current |
|
||||
| `John Trozzi` | DENY | current |
|
||||
| `Karen Rossini` | DENY | current |
|
||||
| `Lois Lane` | DENY | current |
|
||||
| `Lupe Sanchez` | DENY | current |
|
||||
| `mcnurse` | DENY | ROLE (HIPAA concern) |
|
||||
| `Memcare Receptionist` | DENY | ROLE (HIPAA concern) |
|
||||
| `memcarenurse` | DENY | ROLE (HIPAA concern) |
|
||||
| `meredith kuhn` | DENY | current |
|
||||
| `Nela Durut-Azizi` | DENY | DEPARTED |
|
||||
| `Nurse Tower` | DENY | ROLE (HIPAA concern) |
|
||||
| `Shelby Trozzi` | DENY | current |
|
||||
| `Susan Hicks` | DENY | current |
|
||||
| `Tamra Johnson` | DENY | DEPARTED |
|
||||
| `Veronica` | RW | current |
|
||||
| `VPNClient` | DENY | service/admin |
|
||||
|
||||
### Share: `Server`
|
||||
|
||||
**Groups:**
|
||||
|
||||
| Group | Effective |
|
||||
|---|---|
|
||||
| `MainOffice` | RW |
|
||||
| `administrators` | RW |
|
||||
| `http` | - |
|
||||
| `users` | - |
|
||||
|
||||
**Users with explicit permission:**
|
||||
|
||||
| User | Effective | Status |
|
||||
|---|---|---|
|
||||
| `Accounting` | DENY | ROLE (HIPAA concern) |
|
||||
| `admin` | RW | service/admin |
|
||||
| `Anna Pitzlin` | DENY | DEPARTED |
|
||||
| `Ashley Jensen` | RW | current |
|
||||
| `Britney Thompson` | RW | DEPARTED |
|
||||
| `CasAdmin201` | RW | current |
|
||||
| `ChristinaDupras` | RW | current |
|
||||
| `Crystal Rodriguez` | DENY | current |
|
||||
| `Crystal Suszek` | DENY | current |
|
||||
| `Dining Manager` | DENY | ROLE (HIPAA concern) |
|
||||
| `Front Desk` | DENY | ROLE (HIPAA concern) |
|
||||
| `guru` | RW | service/admin |
|
||||
| `Haris Durut` | DENY | DEPARTED |
|
||||
| `JD Martin` | DENY | current |
|
||||
| `John Trozzi` | DENY | current |
|
||||
| `Karen Rossini` | DENY | current |
|
||||
| `Lois Lane` | DENY | current |
|
||||
| `Lupe Sanchez` | DENY | current |
|
||||
| `Memcare Receptionist` | DENY | ROLE (HIPAA concern) |
|
||||
| `meredith kuhn` | Admin(full) | current |
|
||||
| `Nela Durut-Azizi` | DENY | DEPARTED |
|
||||
| `Nurse Tower` | DENY | ROLE (HIPAA concern) |
|
||||
| `Shelby Trozzi` | Admin(full) | current |
|
||||
| `Tamra Johnson` | DENY | DEPARTED |
|
||||
| `Veronica` | RW | current |
|
||||
|
||||
### Share: `chat`
|
||||
|
||||
**Groups:**
|
||||
|
||||
| Group | Effective |
|
||||
|---|---|
|
||||
| `MainOffice` | DENY |
|
||||
| `administrators` | RW |
|
||||
| `http` | - |
|
||||
| `users` | - |
|
||||
|
||||
**Users with explicit permission:**
|
||||
|
||||
| User | Effective | Status |
|
||||
|---|---|---|
|
||||
| `Accounting` | DENY | ROLE (HIPAA concern) |
|
||||
| `admin` | RW | service/admin |
|
||||
| `Anna Pitzlin` | DENY | DEPARTED |
|
||||
| `Ashley Jensen` | RW | current |
|
||||
| `Britney Thompson` | RW | DEPARTED |
|
||||
| `CasAdmin201` | RW | current |
|
||||
| `ChristinaDupras` | DENY | current |
|
||||
| `Crystal Rodriguez` | DENY | current |
|
||||
| `Crystal Suszek` | DENY | current |
|
||||
| `Dining Manager` | DENY | ROLE (HIPAA concern) |
|
||||
| `guru` | RW | service/admin |
|
||||
| `Haris Durut` | DENY | DEPARTED |
|
||||
| `JD Martin` | DENY | current |
|
||||
| `John Trozzi` | DENY | current |
|
||||
| `Karen Rossini` | DENY | current |
|
||||
| `Lois Lane` | DENY | current |
|
||||
| `Lupe Sanchez` | DENY | current |
|
||||
| `mcnurse` | DENY | ROLE (HIPAA concern) |
|
||||
| `Memcare Receptionist` | DENY | ROLE (HIPAA concern) |
|
||||
| `memcarenurse` | DENY | ROLE (HIPAA concern) |
|
||||
| `meredith kuhn` | Admin(full) | current |
|
||||
| `Nela Durut-Azizi` | DENY | DEPARTED |
|
||||
| `Nurse Tower` | DENY | ROLE (HIPAA concern) |
|
||||
| `Shelby Trozzi` | Admin(full) | current |
|
||||
| `Tamra Johnson` | DENY | DEPARTED |
|
||||
| `Veronica` | RW | current |
|
||||
|
||||
### Share: `homes`
|
||||
|
||||
**Groups:**
|
||||
|
||||
| Group | Effective |
|
||||
|---|---|
|
||||
| `MainOffice` | RW |
|
||||
| `administrators` | RW |
|
||||
| `http` | - |
|
||||
| `users` | - |
|
||||
|
||||
**Users with explicit permission:**
|
||||
|
||||
| User | Effective | Status |
|
||||
|---|---|---|
|
||||
| `admin` | RW | service/admin |
|
||||
| `Ashley Jensen` | RW | current |
|
||||
| `Britney Thompson` | RW | DEPARTED |
|
||||
| `CasAdmin201` | RW | current |
|
||||
| `Front Desk` | DENY | ROLE (HIPAA concern) |
|
||||
| `guru` | RW | service/admin |
|
||||
| `Karen Rossini` | RW | current |
|
||||
| `Lois Lane` | DENY | current |
|
||||
| `meredith kuhn` | Admin(full) | current |
|
||||
| `Nurse Tower` | DENY | ROLE (HIPAA concern) |
|
||||
| `Shelby Trozzi` | Admin(full) | current |
|
||||
| `Stephanie Devin` | RW | current |
|
||||
| `Veronica` | RW | current |
|
||||
|
||||
### Share: `pacs`
|
||||
|
||||
**Groups:**
|
||||
|
||||
| Group | Effective |
|
||||
|---|---|
|
||||
| `MainOffice` | DENY |
|
||||
| `administrators` | RW |
|
||||
| `http` | - |
|
||||
| `users` | - |
|
||||
|
||||
**Users with explicit permission:**
|
||||
|
||||
| User | Effective | Status |
|
||||
|---|---|---|
|
||||
| `Accounting` | DENY | ROLE (HIPAA concern) |
|
||||
| `admin` | RW | service/admin |
|
||||
| `Ann Dery` | DENY | DEPARTED |
|
||||
| `Anna Pitzlin` | DENY | DEPARTED |
|
||||
| `Ashley Jensen` | RW | current |
|
||||
| `Britney Thompson` | RW | DEPARTED |
|
||||
| `CasAdmin201` | RW | current |
|
||||
| `ChristinaDupras` | DENY | current |
|
||||
| `Crystal Rodriguez` | DENY | current |
|
||||
| `Crystal Suszek` | DENY | current |
|
||||
| `Dining Manager` | DENY | ROLE (HIPAA concern) |
|
||||
| `Front Desk` | DENY | ROLE (HIPAA concern) |
|
||||
| `guest` | DENY | service/admin |
|
||||
| `guru` | RW | service/admin |
|
||||
| `Haris Durut` | DENY | DEPARTED |
|
||||
| `JD Martin` | DENY | current |
|
||||
| `John Trozzi` | DENY | current |
|
||||
| `Karen Rossini` | DENY | current |
|
||||
| `Lois Lane` | DENY | current |
|
||||
| `Lupe Sanchez` | DENY | current |
|
||||
| `mcnurse` | DENY | ROLE (HIPAA concern) |
|
||||
| `Megan Hiatt` | DENY | current |
|
||||
| `Memcare Receptionist` | DENY | ROLE (HIPAA concern) |
|
||||
| `memcarenurse` | DENY | ROLE (HIPAA concern) |
|
||||
| `meredith kuhn` | DENY | current |
|
||||
| `Nela Durut-Azizi` | DENY | DEPARTED |
|
||||
| `Nurse Tower` | DENY | ROLE (HIPAA concern) |
|
||||
| `Shelby Trozzi` | DENY | current |
|
||||
| `Susan Hicks` | DENY | current |
|
||||
| `Tamra Johnson` | DENY | DEPARTED |
|
||||
| `Veronica` | RW | current |
|
||||
| `VPNClient` | DENY | service/admin |
|
||||
|
||||
### Share: `web`
|
||||
|
||||
**Groups:**
|
||||
|
||||
| Group | Effective |
|
||||
|---|---|
|
||||
| `MainOffice` | DENY |
|
||||
| `administrators` | Admin(full) |
|
||||
| `http` | - |
|
||||
| `users` | - |
|
||||
|
||||
**Users with explicit permission:**
|
||||
|
||||
| User | Effective | Status |
|
||||
|---|---|---|
|
||||
| `Accounting` | DENY | ROLE (HIPAA concern) |
|
||||
| `admin` | RW | service/admin |
|
||||
| `Ann Dery` | DENY | DEPARTED |
|
||||
| `Anna Pitzlin` | DENY | DEPARTED |
|
||||
| `Ashley Jensen` | RW | current |
|
||||
| `Britney Thompson` | RW | DEPARTED |
|
||||
| `CasAdmin201` | RW | current |
|
||||
| `ChristinaDupras` | DENY | current |
|
||||
| `Crystal Rodriguez` | DENY | current |
|
||||
| `Crystal Suszek` | DENY | current |
|
||||
| `Dining Manager` | DENY | ROLE (HIPAA concern) |
|
||||
| `Front Desk` | DENY | ROLE (HIPAA concern) |
|
||||
| `guest` | DENY | service/admin |
|
||||
| `guru` | RW | service/admin |
|
||||
| `Haris Durut` | DENY | DEPARTED |
|
||||
| `JD Martin` | DENY | current |
|
||||
| `John Trozzi` | DENY | current |
|
||||
| `Karen Rossini` | DENY | current |
|
||||
| `Lois Lane` | DENY | current |
|
||||
| `Lupe Sanchez` | DENY | current |
|
||||
| `mcnurse` | DENY | ROLE (HIPAA concern) |
|
||||
| `Megan Hiatt` | DENY | current |
|
||||
| `Memcare Receptionist` | DENY | ROLE (HIPAA concern) |
|
||||
| `memcarenurse` | DENY | ROLE (HIPAA concern) |
|
||||
| `meredith kuhn` | DENY | current |
|
||||
| `Monica RamirezRossette` | RW | DEPARTED |
|
||||
| `Nela Durut-Azizi` | DENY | DEPARTED |
|
||||
| `Nurse Tower` | DENY | ROLE (HIPAA concern) |
|
||||
| `Shelby Trozzi` | DENY | current |
|
||||
| `Susan Hicks` | DENY | current |
|
||||
| `Tamra Johnson` | DENY | DEPARTED |
|
||||
| `Veronica` | RW | current |
|
||||
| `VPNClient` | DENY | service/admin |
|
||||
@@ -0,0 +1,259 @@
|
||||
# CS-SERVER Entra Connect Readiness Check - POST-REBOOT
|
||||
|
||||
**Command ID:** fe50258c-4005-4b1a-b559-106023df5d6a
|
||||
**Run at:** 2026-04-23T01:54:13.869657Z
|
||||
**Completed:** 2026-04-23T01:55:27.360715Z
|
||||
**Exit code:** 0
|
||||
|
||||
## STDOUT
|
||||
|
||||
```
|
||||
Entra Connect Readiness Check - 2026-04-22 18:54:22 -07:00
|
||||
|
||||
Host: CS-SERVER
|
||||
|
||||
|
||||
|
||||
============================================================================
|
||||
|
||||
== 1. Operating System
|
||||
|
||||
============================================================================
|
||||
|
||||
OS Caption : Microsoft Windows Server 2019 Standard
|
||||
|
||||
OS Version : 10.0.17763
|
||||
|
||||
OS Build : 17763
|
||||
|
||||
Architecture : 64-bit
|
||||
|
||||
Install Date : 8/4/2024 6:39:38 PM
|
||||
|
||||
Last Boot : 4/22/2026 6:29:20 PM
|
||||
|
||||
Uptime (days) : 0
|
||||
|
||||
[OK] Server 2016+ required : Microsoft Windows Server 2019 Standard -> PASS
|
||||
|
||||
|
||||
|
||||
============================================================================
|
||||
|
||||
== 2. .NET Framework version
|
||||
|
||||
============================================================================
|
||||
|
||||
.NET Framework version : System.Object[]
|
||||
|
||||
.NET release key : 528049
|
||||
|
||||
[OK] .NET 4.7.2+ required : 4.8 4.7.2 4.7.1 4.7 4.6.2 -> PASS
|
||||
|
||||
|
||||
|
||||
============================================================================
|
||||
|
||||
== 3. PowerShell
|
||||
|
||||
============================================================================
|
||||
|
||||
PSVersion : 5.1.17763.8641
|
||||
|
||||
PSEdition : Desktop
|
||||
|
||||
[OK] PS 5.0+ required : 5.1.17763.8641 -> PASS
|
||||
|
||||
|
||||
|
||||
============================================================================
|
||||
|
||||
== 4. TLS 1.2 configuration
|
||||
|
||||
============================================================================
|
||||
|
||||
.NET SchUseStrongCrypto (64-bit) : 1
|
||||
|
||||
.NET SchUseStrongCrypto (32-bit) : 1
|
||||
|
||||
.NET SystemDefaultTlsVersions (64) : 1
|
||||
|
||||
.NET SystemDefaultTlsVersions (32) : 1
|
||||
|
||||
SCHANNEL TLS 1.0 Client : Enabled=0 DisabledByDefault=1
|
||||
|
||||
SCHANNEL TLS 1.1 Client : Enabled=0 DisabledByDefault=1
|
||||
|
||||
SCHANNEL TLS 1.2 Client : Enabled=1 DisabledByDefault=0
|
||||
|
||||
SCHANNEL TLS 1.0 Server : Enabled=0 DisabledByDefault=1
|
||||
|
||||
SCHANNEL TLS 1.1 Server : Enabled=0 DisabledByDefault=1
|
||||
|
||||
SCHANNEL TLS 1.2 Server : Enabled=1 DisabledByDefault=0
|
||||
|
||||
(Entra Connect requires TLS 1.2 client enabled; TLS 1.0/1.1 should be disabled per HIPAA best practice.)
|
||||
|
||||
|
||||
|
||||
============================================================================
|
||||
|
||||
== 5. Disk space
|
||||
|
||||
============================================================================
|
||||
|
||||
Drive C: : 149.3 GB free of 296.9 GB (50.3% free)
|
||||
|
||||
Drive D: : 548.5 GB free of 1117.2 GB (49.1% free)
|
||||
|
||||
(Entra Connect needs ~5-20 GB free on install drive, typically C:.)
|
||||
|
||||
|
||||
|
||||
============================================================================
|
||||
|
||||
== 6. AD Domain + FSMO roles
|
||||
|
||||
============================================================================
|
||||
|
||||
Domain : cascades.local
|
||||
|
||||
NetBIOS name : CASCADES
|
||||
|
||||
Forest mode : Windows2016Forest
|
||||
|
||||
Domain mode : Windows2016Domain
|
||||
|
||||
Schema master : CS-SERVER.cascades.local
|
||||
|
||||
Domain naming master : CS-SERVER.cascades.local
|
||||
|
||||
PDC emulator : CS-SERVER.cascades.local
|
||||
|
||||
RID master : CS-SERVER.cascades.local
|
||||
|
||||
Infrastructure master : CS-SERVER.cascades.local
|
||||
|
||||
AD user count : 44
|
||||
|
||||
AD group count : 55
|
||||
|
||||
AD OU count : 18
|
||||
|
||||
|
||||
|
||||
============================================================================
|
||||
|
||||
== 7. AD Schema version
|
||||
|
||||
============================================================================
|
||||
|
||||
Schema objectVersion : 88
|
||||
|
||||
Schema version (mapped) : Windows Server 2019
|
||||
|
||||
|
||||
|
||||
============================================================================
|
||||
|
||||
== 8. Time sync
|
||||
|
||||
============================================================================
|
||||
|
||||
(Entra Connect requires clock within ~5 min of Microsoft time.)
|
||||
|
||||
Leap Indicator: 0(no warning)
|
||||
|
||||
Stratum: 2 (secondary reference - syncd by (S)NTP)
|
||||
|
||||
Precision: -23 (119.209ns per tick)
|
||||
|
||||
Root Delay: 0.0470007s
|
||||
|
||||
Root Dispersion: 0.0759468s
|
||||
|
||||
ReferenceId: 0x84A36103 (source IP: 132.163.97.3)
|
||||
|
||||
Last Successful Sync Time: 4/22/2026 6:53:55 PM
|
||||
|
||||
Source: time.nist.gov,0x8
|
||||
|
||||
Poll Interval: 8 (256s)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#Peers: 3
|
||||
|
||||
|
||||
|
||||
Peer: pool.ntp.org,0x8
|
||||
|
||||
State: Active
|
||||
|
||||
Time Remaining: 74.4687716s
|
||||
|
||||
Mode: 3 (Client)
|
||||
|
||||
Stratum: 2 (secondary reference - syncd by (S)NTP)
|
||||
|
||||
PeerPoll Interval: 8 (256s)
|
||||
|
||||
HostPoll Interval: 8 (256s)
|
||||
|
||||
|
||||
|
||||
Peer: time.windows.com,0x8
|
||||
|
||||
State: Active
|
||||
|
||||
Time Remaining: 202.5990796s
|
||||
|
||||
Mode: 3 (Client)
|
||||
|
||||
Stratum: 3 (secondary reference - syncd by (S)NTP)
|
||||
|
||||
PeerPoll Interval: 8 (256s)
|
||||
|
||||
HostPoll Interval: 8 (256s)
|
||||
|
||||
|
||||
|
||||
Peer: time.nist.gov,0x8
|
||||
|
||||
State: Active
|
||||
|
||||
Time Remaining: 203.5668662s
|
||||
|
||||
Mode: 3 (Client)
|
||||
|
||||
Stratum: 1 (primary reference - syncd by radio clock)
|
||||
|
||||
PeerPoll Interval: 13 (8192s)
|
||||
|
||||
HostPoll Interval: 8 (256s)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
============================================================================
|
||||
|
||||
== 9. Internet connectivity to Microsoft sync endpoints
|
||||
|
||||
============================================================================
|
||||
|
||||
[OK] HTTPS 443 -> login.microsoftonline.com : True
|
||||
|
||||
[OK] HTTPS 443 -> login.windows.net : True
|
||||
|
||||
[OK] HTTPS 443 -> secure.aadcdn.microsoftonline-p.com: True
|
||||
|
||||
[OK] HTTPS 443 -> management.azure.com : True
|
||||
|
||||
[OK] HTTPS 443 -> graph.windows.net : True
|
||||
|
||||
[OK] HTTPS 443 -> adminwebservice.microsoftonline.com: True
|
||||
|
||||
[OK] HTTPS 443 -> provisioningapi.microsoftonline.com: True
|
||||
@@ -0,0 +1,82 @@
|
||||
# CS-SERVER Pre-flight Verification — POST-REBOOT (2026-04-22)
|
||||
|
||||
**Reboot completed:** 2026-04-22 18:29 MST (per Last Boot time in readiness check)
|
||||
**Verification run:** 2026-04-22 18:54 MST (via GuruRMM agent, exit code 0)
|
||||
**Result file:** `reports/2026-04-22-cs-server-entra-readiness-post-reboot.md`
|
||||
|
||||
## Verdict: Ready for Entra Connect install
|
||||
|
||||
All three pre-install items applied successfully and survived the reboot.
|
||||
|
||||
### 1. Time sync — FIXED
|
||||
|
||||
| Before | After |
|
||||
|---|---|
|
||||
| `Source: Free-running System Clock` | `Source: time.nist.gov,0x8` |
|
||||
| `ReferenceId: 0x4C4F434C (LOCL)` | `ReferenceId: 0x84A36103 (source IP: 132.163.97.3)` |
|
||||
| Stratum: 1 (local clock) | Stratum: 2 (secondary reference, NTP-synced) |
|
||||
| Last sync: 21 hours ago | Last sync: 0 minutes ago |
|
||||
| 0 peers active | 3 peers active (pool.ntp.org, time.windows.com, time.nist.gov) |
|
||||
|
||||
### 2. TLS 1.2 enforcement — FIXED
|
||||
|
||||
| Setting | Before | After |
|
||||
|---|---|---|
|
||||
| `.NET SchUseStrongCrypto (64-bit)` | 1 | 1 |
|
||||
| `.NET SchUseStrongCrypto (32-bit)` | (unset) | **1** |
|
||||
| `.NET SystemDefaultTlsVersions (64)` | (unset) | **1** |
|
||||
| `.NET SystemDefaultTlsVersions (32)` | (unset) | **1** |
|
||||
| SCHANNEL TLS 1.0 Client | (OS default) | **Enabled=0, DisabledByDefault=1** |
|
||||
| SCHANNEL TLS 1.1 Client | (OS default) | **Enabled=0, DisabledByDefault=1** |
|
||||
| SCHANNEL TLS 1.2 Client | (OS default) | **Enabled=1, DisabledByDefault=0** |
|
||||
| SCHANNEL TLS 1.0 Server | (OS default) | **Enabled=0, DisabledByDefault=1** |
|
||||
| SCHANNEL TLS 1.1 Server | (OS default) | **Enabled=0, DisabledByDefault=1** |
|
||||
| SCHANNEL TLS 1.2 Server | (OS default) | **Enabled=1, DisabledByDefault=0** |
|
||||
|
||||
### 3. Windows Server Backup — INSTALLED
|
||||
|
||||
| Before | After |
|
||||
|---|---|
|
||||
| Windows-Server-Backup: Available (not installed) | **Windows-Server-Backup: Installed** |
|
||||
|
||||
## Other observations
|
||||
|
||||
- **Uptime:** 0 days (fresh reboot at 18:29 MST)
|
||||
- **PowerShell:** 5.1.17763.8641 (minor patch bump from 5.1.17763.8510 — Windows Updates applied during reboot)
|
||||
- **RAM usage:** 7.9 GB / 47.9 GB (16%) — down from 12.8 GB before reboot, caches clean
|
||||
- **CPU:** 22% at moment of check — elevated vs pre-reboot but within normal boot settling range
|
||||
- **DC health dcdiag:** Connectivity / Advertising / Services / FsmoCheck all **PASS**
|
||||
- **Microsoft sync endpoints:** all 7 still reach on HTTPS 443
|
||||
- **QuickBooksDB34 service:** now Running (was Stopped pre-reboot — QB auto-started)
|
||||
|
||||
## Event log noise (not blockers)
|
||||
|
||||
Post-reboot noise is expected and benign. 19 System errors / 15 Application errors in last 24h, top sources:
|
||||
|
||||
| Source | Count | Nature |
|
||||
|---|---:|---|
|
||||
| Hyper-V-VmSwitch | 6 | VM startup ordering |
|
||||
| VSS | 6 | QuickBooks VSS writer reconnecting |
|
||||
| Service Control Manager | 4 | Service start dependency ordering |
|
||||
| Schannel | 4 | TLS reconnect post-reboot (consistent with the TLS changes) |
|
||||
| Security-SPP | 4 | Windows activation checks |
|
||||
| DistributedCOM | 3 | Normal service-start race |
|
||||
| .NET Runtime | 2 | App process restart errors |
|
||||
| TPM-WMI | 2 | Benign on non-TPM hardware |
|
||||
| Perflib | 2 | Counter registration |
|
||||
| Firefox agent | 1 | Noise |
|
||||
|
||||
None critical, no AD-related errors, no sync-impacting items.
|
||||
|
||||
## Next step
|
||||
|
||||
Entra Connect install can proceed at your next maintenance window. The build-up state is:
|
||||
|
||||
- [x] Wave 0 HIPAA items — most still pending (M365 BAA sign, ALIS BAA, risk analysis, etc.) — see `docs/security/hipaa-review-2026-04-22.md`
|
||||
- [x] **Wave 0.5 CS-SERVER readiness — DONE**
|
||||
- [ ] Install Microsoft Entra Connect on CS-SERVER (staging-mode first)
|
||||
- [ ] Apply Wave 0.5 AD cleanup (renames, UPN suffix add, former-employee deletes) per rollout plan §7
|
||||
- [ ] Convert M365 role-based accounts to shared mailboxes (frees 11 licenses, clean identity targets)
|
||||
- [ ] Exit staging + enable sync
|
||||
|
||||
The TLS reboot also fulfils an independent HIPAA hygiene fix for the whole tenant (per `docs/security/hipaa.md` gap tracking). Net benefit beyond Entra Connect prep.
|
||||
Reference in New Issue
Block a user