sync: auto-sync from HOWARD-HOME at 2026-06-05 16:17:06

Author: Howard Enos
Machine: HOWARD-HOME
Timestamp: 2026-06-05 16:17:06
This commit is contained in:
2026-06-05 16:17:15 -07:00
parent fc36218960
commit f5bdec125a
3 changed files with 174 additions and 2 deletions

View File

@@ -0,0 +1,111 @@
#
# Windows PowerShell script to configure the SCP for Hybrid Azure AD join
#
# CASCADES OF TUCSON - preconfigured copy (from Entra Connect, 2026-06-05)
# Tenant (azureADId) is baked in below: 207fa277-e9d8-4eb7-ada1-1064d2221498
# -Domain defaults to cascadestucson.com so this runs self-contained.
#
# HOW TO RUN: on a Domain Controller (CS-SERVER) in an ELEVATED PowerShell,
# as an ENTERPRISE ADMIN of cascades.local:
# .\ConfigureSCP.ps1
# (idempotent - creates the SCP if missing, updates the keywords if present)
#
# WHY: writes the Service Connection Point into AD's Configuration partition so
# domain-joined devices can discover the Entra tenant and Hybrid Entra Join.
#
param([string]$Domain = "cascadestucson.com", [switch]$Help)
function funHelp()
{
$helpTxt = @"
NAME: ConfigureSCP.ps1
PURPOSE: Configures the service connection point for Hybrid Azure AD join in the current forest
REQUIREMENT: Must be run by an Enterprise Admin of the current forest
PARAMETERS:
-Domain <NAME> Specifies the Azure AD domain to use for device authentication
If you are using federation to authenticate with Azure AD, enter a federated domain name.
If you are not using federation, enter your primary *.onmicrosoft.com domain name.
(Cascades default: cascadestucson.com)
-Help Prints the help file
EXAMPLES:
1. ConfigureSCP.ps1 (uses cascadestucson.com)
2. ConfigureSCP.ps1 -Domain cascadestucson.com
"@
$helpTxt
exit 1
}
if ($Help)
{
funHelp
}
if (-not($Domain))
{
Write-Output "You must specify a value for -Domain"
funhelp
}
Write-Output "Configuring the SCP for Hybrid Azure AD join in your Active Directory forest."
## Set variables
$azureADId = "azureADId:207fa277-e9d8-4eb7-ada1-1064d2221498"
$azureADName = "azureADName:" + $Domain
$keywords = "keywords"
$ldap = "LDAP://"
$rootDSE = New-Object System.DirectoryServices.DirectoryEntry($ldap + "RootDSE")
$configCN = $rootDSE.Properties["configurationNamingContext"][0].ToString()
$servicesCN = "CN=Services," + $configCN
$drcCN = "CN=Device Registration Configuration," + $servicesCN
$scpCN = "CN=62a0ff2e-97b9-4513-943f-0d221bd30080," + $drcCN
## Get/Create: CN=Device Registration Configuration,CN=Services
if ([System.DirectoryServices.DirectoryEntry]::Exists($ldap + $drcCN))
{
$deDRC = New-Object System.DirectoryServices.DirectoryEntry($ldap + $drcCN)
}
else
{
$de = New-Object System.DirectoryServices.DirectoryEntry($ldap + $servicesCN)
$deDRC = $de.Children.Add("CN=Device Registration Configuration", "container")
$deDRC.CommitChanges()
}
## Edit/Create: CN=62a0ff2e-97b9-4513-943f-0d221bd30080,CN=Device Registration Configuration,CN=Services
if ([System.DirectoryServices.DirectoryEntry]::Exists($ldap + $scpCN))
{
$deSCP = New-Object System.DirectoryServices.DirectoryEntry($ldap + $scpCN)
foreach ($value in $deSCP.Properties[$keywords].Value)
{
$deSCP.Properties[$keywords].Remove($value)
}
$deSCP.Properties[$keywords].Add($azureADName)
$deSCP.Properties[$keywords].Add($azureADId)
$deScp.CommitChanges()
}
else
{
$deSCP = $deDRC.Children.Add("CN=62a0ff2e-97b9-4513-943f-0d221bd30080", "serviceConnectionPoint")
$deSCP.Properties[$keywords].Add($azureADName)
$deSCP.Properties[$keywords].Add($azureADId)
$deScp.CommitChanges()
}
if ($Error)
{
Write-Output "Configuration could not be completed."
Write-Output $Error
}
else
{
Write-Output "Configuration complete!"
}

View File

@@ -173,3 +173,57 @@ Entra Connect syncs USERS (PHS + Seamless SSO) — that's set up. **Hybrid Azure
- [ ] GPO for caregiver devices: disable Windows Hello (`Use Windows Hello for Business`=Disabled), idle screen-lock (machine inactivity limit), security baseline; folder handling so no local data.
- [ ] Users sign in with **email/UPN** (works on domain/hybrid devices since UPN suffix = cascadestucson.com). Each caregiver uses their OWN account (shared device, individual logins) — required for ALIS SSO email-match + audit.
- [ ] Resume per-user testing via `SG-Caregivers-DeviceTest`, then promote to `SG-Caregivers`.
## Update: 16:14 MST — Hybrid join COMPLETE + ALIS SSO validated end-to-end; caregiver GPO build in progress
### MILESTONE: NURSESTATION hybrid-joined, pilot.test ALIS SSO works on a desktop
The whole hybrid pivot is proven on one machine:
- Added `OU=Caregiver Devices,OU=Staff PCs,OU=Workstations` to the **Entra Connect sync scope** (Optional features left as-is: PHS + Password writeback on; Group writeback + Device writeback OFF — neither is needed for Hybrid Join). Ran `Start-ADSyncSyncCycle` (a full sync was already auto-running from the wizard "Configure"); all connector runs **success**.
- NURSESTATION computer object synced to Entra as **`trustType: ServerAd`** (= Hybrid Entra Join). New **deviceId `d3bf931f-f128-4261-8398-b46c34a4b342`** (object id `de199a15-3f5d-4da3-8b17-3faade7f7dad`).
- On reboot, client-side join completed: `dsregcmd /status`**AzureAdJoined: YES, DomainJoined: YES (CASCADES)**, DeviceAuthStatus SUCCESS, TpmProtected YES.
- As **pilot.test** (non-elevated `dsregcmd`): **AzureAdPrt: YES** → PRT issued, silent SSO chain complete. **ALIS opened via silent SSO — no second credential prompt. Full caregiver desktop experience validated.**
- `Ngc Prerequisite Check` = `PolicyEnabled: NO``WillNotProvision` = **Windows Hello will NOT auto-provision** on hybrid-joined machines (PIN/Hello popup does not appear). This is the behavior we want for shared caregiver devices — no separate Hello-disable step needed on the hybrid path.
### Allow-list CA rule updated to the NEW deviceId (the old one was stale)
Removing Entra + re-domain-joining created a brand-new device object. Old Entra-joined deviceId `e16c4af5-cb0e-49e1-90be-674a216f5e9c` no longer exists in Entra (confirmed empty lookup).
- Policy `CSC - Caregivers: allow-listed devices only (TEST GROUP)` (`1b7fd025-1aad-47c8-9274-c32c3e0b163c`, deviceFilter mode=**exclude** = allow-list) rule now:
`(device.displayName -startsWith "CSC-") -or (device.extensionAttribute1 -eq "CSCCaregiverDevice") -or (device.deviceId -eq "d3bf931f-f128-4261-8398-b46c34a4b342")`
- Also tagged the device `extensionAttribute1 = CSCCaregiverDevice` (durable; survives future deviceId changes). NURSESTATION now allow-listed by deviceId (lag-free) AND tag.
- Reminder (Graph): PATCH returns 204 then read-back lags a few seconds (replication) — re-read to confirm.
### Reception-policy false alarm (resolved, no change made)
`CSC - Reception Workstation Policy` showed as "inherited" by `OU=Caregiver Devices` (it's linked at parent `OU=Staff PCs`), but its **security filtering is `GpoApply: SG-Reception-PCs` only**, and that group contains **only RECEPTIONIST-PC**. So it never applies to NURSESTATION. Nothing unlinked. (`Get-GPInheritance` lists in-scope links before security filtering.)
### NEW WORK: proper GPO for all caregivers/medtechs (shortcuts + printers) — IN PROGRESS
Decision (per Howard): do NOT place shortcuts/printers manually — build a real, scalable GPO driven by the SG/OU structure ("how a medical company should work"), and **mirror it in a test scope (pilot.test only) so the 38 real caregivers are untouched** until validated.
**Discovery:**
- **CS-SERVER is the print server** (15 shared queues `\\CS-SERVER\<share>`).
- `SG-Caregivers` = real on-prem Global Security group, **38 members**, `OU=Groups` — same group synced to Entra for the CA policies (one group drives GPO + CA).
- All 38 caregivers live in `OU=Caregivers,OU=Departments` (42 users total there; others: c.lassey, p.sandoval-beck [likely medtechs to add], n.castro [TERMINATED], pilot.test).
- pilot.test DN = `CN=Pilot Test,OU=Caregivers,OU=Departments` (correct OU), no on-prem groups.
- Existing printer GPOs: `CSC - Life Enrichment Printers` (WORKING, linked to OU=Life Enrichment) and **`CSC - Printer Deployment` which is BROKEN** — it has a full User Printers.xml (all departments, ILT by OU/group) but **`gPCUserExtensionNames` is EMPTY and `versionNumber=0`**, so the CSE is unregistered and it never applies even if linked. (It also has a bug: the NursesPrinter entry path is `\CS-SERVER\NursesPrinter` — single backslash. Worth fixing/retiring this GPO separately.)
**Proven GPP schema cloned from this domain (for the new GPO):**
- Working `gPCUserExtensionNames` for **Printers** = `[{00000000-0000-0000-0000-000000000000}{A8C42CEA-CDB8-4388-97F4-5831F933DA84}][{BC75B1ED-5833-4858-9BB8-CBF0B166DF9D}{A8C42CEA-CDB8-4388-97F4-5831F933DA84}]` (tool-ext GUID this domain uses = `{A8C42CEA-CDB8-4388-97F4-5831F933DA84}`).
- To ADD **Shortcuts** CSE, append `[{C418DD9D-0D14-4efb-8FBF-CFE535C8FAC7}{A8C42CEA-CDB8-4388-97F4-5831F933DA84}]` (CSE GUIDs stay sorted: 00000000 < BC75 < C418). Must also bump `versionNumber`.
- Printers.xml: `<Printers clsid="{1F577D12-...}">``<SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="\\CS-SERVER\<share>" ...><Properties action="U|C" path="\\CS-SERVER\<share>" default="0|1" skipLocal="1" ...><Filters>...</Filters></Properties></SharedPrinter>`. **Filters go INSIDE `<Properties>`.** `FilterGroup ... userContext="1"` = check USER's group; **`userContext="0"` = check COMPUTER's group** (this is how device-location default targeting works).
**GROUPS CREATED this session (in `OU=Groups`):**
- `SG-Caregivers-Test` — GPO security-filter for the pilot. Member: **pilot.test** only. (Go-live = swap filter to `SG-Caregivers`.)
- `SG-PC-MainTower` — caregiver DEVICE location = main tower / assisted living. Member: **NURSESTATION-PC**. Drives default-printer = Nurses via ILT (computer context).
- `SG-PC-MemoryCare` — caregiver DEVICE location = memory care. Empty (ready). Drives default-printer = MC MedTech.
**Design — GPO `CSC - Caregiver Workstation` (User config GPP), NOT YET CREATED:**
- Shortcuts (Desktop): **ALIS** `https://cascadestucson.alisonline.com/Login`, **LinkRx** `https://pharmcare.linkrxnow.com/Login.aspx`, **Safe Living** `https://app.safe-living.com/login`. (Existing ALIS/LinkRx today are per-profile `.url` files placed manually — this GPO replaces that.)
- Printers (Howard-approved set, all `\\CS-SERVER\`): `NursesPrinter`, `HealthServices`, `MCMedTech`, `MCReception`, `MCDirector`, `CopyRoom` — deployed to all (no filter). Plus conditional default via two extra `default="1"` entries with ILT: `NursesPrinter` when computer ∈ `SG-PC-MainTower`; `MCMedTech` when computer ∈ `SG-PC-MemoryCare` (`userContext="0"`).
- Link at `OU=Caregivers,OU=Departments`; **security filter = `SG-Caregivers-Test`** (remove Authenticated Users Apply) so only pilot.test applies it; 38 real caregivers see it in scope but filtered out = zero impact.
- Set `gPCUserExtensionNames` (printers+shortcuts CSEs), bump version, set Computer-side disabled.
### Next steps (resume here)
- [ ] Create GPO `CSC - Caregiver Workstation`; write `User\Preferences\Printers\Printers.xml` + `User\Preferences\Shortcuts\Shortcuts.xml`; set `gPCUserExtensionNames` + bump `versionNumber`.
- [ ] Link at `OU=Caregivers,OU=Departments`; set security filtering to `SG-Caregivers-Test` only.
- [ ] Test on NURSESTATION as pilot.test: `gpupdate /force` → logoff/logon → verify 3 desktop shortcuts + 6 printers mapped + Nurses default.
- [ ] When validated: swap GPO filter `SG-Caregivers-Test``SG-Caregivers`; for CA, promote allow-list policy from test group to `SG-Caregivers`; move real caregiver machines into `OU=Caregiver Devices` + correct `SG-PC-*` location group one at a time; ALIS email-match the 38 + medtechs.
- [x] `CSC - Printer Deployment` (domain-wide, empty CSE/version 0) is **intentionally not enabled and is NOT to be used domain-wide** (per Howard). Leave it alone — do not link, enable, or "fix" it. Our entire scope is the single caregiver/medtech GPO. It's useful only as a read-only reference for printer shares/ILT examples.
- [ ] Microsoft case for `INTUNE_A PendingInput` (independent — does NOT block caregiver access; the hybrid+GPO path replaces the Intune dependency).