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:
111
clients/cascades-tucson/scripts/ConfigureSCP.ps1
Normal file
111
clients/cascades-tucson/scripts/ConfigureSCP.ps1
Normal 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!"
|
||||
}
|
||||
@@ -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).
|
||||
|
||||
@@ -83,9 +83,16 @@ Senior living / assisted living facility in Tucson, AZ. Single 6-floor building
|
||||
### ALIS SSO
|
||||
- Entra app registration -> OIDC SSO into ALIS; **tenant-wide admin consent granted** (2026-06-03). Per-user join key = **ALIS staff Email must equal the Entra UPN**. Caregivers SSO silently on phones (ALIS-native 2FA off); office users SSO with offsite MFA.
|
||||
|
||||
### Caregiver desktop/laptop management — Hybrid Entra Join + GPO (the chosen path)
|
||||
Because per-user **Intune** never provisioned tenant-wide (`INTUNE_A = PendingInput`; no Windows device ever Intune-enrolled — MS case open), Windows caregiver devices are managed via **Hybrid Entra Join + on-prem Group Policy** instead. This needs no Intune. The CA access model is unchanged (hybrid join just gives the device an Entra object so the allow-list/deviceId still applies).
|
||||
- **Hybrid join proven on NURSESTATION-PC** (2026-06-05): SCP written (`ConfigureSCP.ps1`), `OU=Caregiver Devices,OU=Staff PCs,OU=Workstations` added to Entra Connect sync scope → device synced to Entra as `trustType: ServerAd`, `dsregcmd` shows AzureAdJoined+DomainJoined YES, pilot.test gets `AzureAdPrt: YES`. On hybrid-joined machines `Ngc PreReqResult: WillNotProvision` (PolicyEnabled NO) → **Windows Hello does not auto-provision** (no Hello popup) — exactly what shared caregiver devices need, so no separate Hello-disable step.
|
||||
- **Device control is one-at-a-time:** caregiver machine computer objects are moved into `OU=Caregiver Devices` (only that OU is in sync scope) and into a location group `SG-PC-MainTower` or `SG-PC-MemoryCare`. Add a device = move it into the OU + correct location group.
|
||||
- **App + printer delivery GPO `CSC - Caregiver Workstation`** (User-config GPP), linked at `OU=Caregivers,OU=Departments`, security-filtered to the SG so only caregivers/medtechs apply it. **Built/tested against `SG-Caregivers-Test` (pilot.test only)** first — a true mirror of production with zero impact on the 38 real caregivers — then the filter is swapped to `SG-Caregivers` to go live. Contents: 3 desktop shortcuts (ALIS, LinkRx, Safe Living `https://app.safe-living.com/login`) + 6 `\\CS-SERVER` shared printers (NursesPrinter, HealthServices, MCMedTech, MCReception, MCDirector, CopyRoom) with **default printer by device location** (Nurses for MainTower, MC MedTech for MemoryCare, via item-level targeting on the location group, `userContext="0"`). NOTE: the domain-wide `CSC - Printer Deployment` GPO is intentionally disabled (empty CSE / version 0) and is **not** to be used — reference only.
|
||||
|
||||
### Status (as of 2026-06-05)
|
||||
- **Proven working:** the access model — caregiver lockdown + ALIS SSO — end-to-end on a desktop (pilot.test).
|
||||
- **Blocker / pivot:** device-level **Intune** policies (disable Windows Hello, idle-lock, Shared PC Mode profile-cleanup) can't deploy because the tenant's per-user Intune (`INTUNE_A`) won't provision — stuck `PendingInput` tenant-wide; no Windows device has ever Intune-enrolled (Android works via device-token, which needs no per-user Intune). Microsoft case open. **Pivot:** deliver those device settings via **Group Policy** (Hybrid Entra Join / domain join) or local policy — no Intune dependency. Caregiver access itself does NOT depend on Intune.
|
||||
- **Proven working end-to-end on a hybrid-joined desktop (NURSESTATION + pilot.test):** caregiver lockdown (CA off-network block + device allow-list) **and** silent ALIS SSO. The allow-list policy `1b7fd025` carries NURSESTATION's current deviceId `d3bf931f-f128-4261-8398-b46c34a4b342` (the old Entra-joined id `e16c4af5` is stale/deleted) and the device is tagged `extensionAttribute1=CSCCaregiverDevice`.
|
||||
- **In progress:** building the `CSC - Caregiver Workstation` GPO (shortcuts + printers) against the test group; then promote both the GPO filter and the CA allow-list from the test groups to `SG-Caregivers`, moving real machines in one at a time.
|
||||
- **Independent open item:** Microsoft case for `INTUNE_A PendingInput` — does NOT block caregiver access (hybrid+GPO path replaces the Intune dependency).
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user