From 5076f8f4b14389422af058b15a16cc0d91161671 Mon Sep 17 00:00:00 2001 From: Howard Enos Date: Fri, 17 Jul 2026 14:35:55 -0700 Subject: [PATCH] sync: auto-sync from HOWARD-HOME at 2026-07-17 14:35:21 Author: Howard Enos Machine: HOWARD-HOME Timestamp: 2026-07-17 14:35:21 --- .../scripts/applocker-apply-simple.ps1 | 6 ++ .../scripts/applocker-apply.ps1 | 62 +++++++++++++++++++ .../scripts/applocker-recheck-apps.ps1 | 9 +++ .../scripts/applocker-stage.ps1 | 33 ++++++++++ .../scripts/applocker-step1-enable.ps1 | 28 +++++++++ .../scripts/applocker-to-gpo.ps1 | 22 +++++++ .../scripts/applocker-write-xml.ps1 | 25 ++++++++ .../scripts/build-applocker-policy.ps1 | 51 +++++++++++++++ .../scripts/get-applocker-sids.ps1 | 9 +++ ...-07-17-howard-nurse-station-kiosk-build.md | 44 +++++++++++++ 10 files changed, 289 insertions(+) create mode 100644 clients/cascades-tucson/scripts/applocker-apply-simple.ps1 create mode 100644 clients/cascades-tucson/scripts/applocker-apply.ps1 create mode 100644 clients/cascades-tucson/scripts/applocker-recheck-apps.ps1 create mode 100644 clients/cascades-tucson/scripts/applocker-stage.ps1 create mode 100644 clients/cascades-tucson/scripts/applocker-step1-enable.ps1 create mode 100644 clients/cascades-tucson/scripts/applocker-to-gpo.ps1 create mode 100644 clients/cascades-tucson/scripts/applocker-write-xml.ps1 create mode 100644 clients/cascades-tucson/scripts/build-applocker-policy.ps1 create mode 100644 clients/cascades-tucson/scripts/get-applocker-sids.ps1 diff --git a/clients/cascades-tucson/scripts/applocker-apply-simple.ps1 b/clients/cascades-tucson/scripts/applocker-apply-simple.ps1 new file mode 100644 index 00000000..91cfef72 --- /dev/null +++ b/clients/cascades-tucson/scripts/applocker-apply-simple.ps1 @@ -0,0 +1,6 @@ +Set-Service AppIDSvc -StartupType Automatic +Start-Service AppIDSvc -ErrorAction SilentlyContinue +Set-AppLockerPolicy -XmlPolicy "\\cascades.local\SYSVOL\cascades.local\scripts\applocker-caregiver.xml" +Write-Output "AppIDSvc: $((Get-Service AppIDSvc).Status)" +$p = Get-AppLockerPolicy -Local -Xml +Write-Output "Policy applied: $($p.Length) chars" diff --git a/clients/cascades-tucson/scripts/applocker-apply.ps1 b/clients/cascades-tucson/scripts/applocker-apply.ps1 new file mode 100644 index 00000000..56a4821c --- /dev/null +++ b/clients/cascades-tucson/scripts/applocker-apply.ps1 @@ -0,0 +1,62 @@ +$cgSID = 'S-1-5-21-388235164-2207693853-3666415804-1183' +$evSID = 'S-1-1-0' +$adSID = 'S-1-5-32-544' +$msPub = 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US' +$mwPub = 'CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington, C=US' + +# Build deny rules XML fragments for SG-Caregivers +$denyList = @( + @{Id=[guid]::NewGuid(); Name='Edge GameAssist'; Pub=$msPub; Prod='Microsoft.Edge.GameAssist'}, + @{Id=[guid]::NewGuid(); Name='Paint'; Pub=$msPub; Prod='Microsoft.MSPaint'}, + @{Id=[guid]::NewGuid(); Name='Photos'; Pub=$msPub; Prod='Microsoft.Windows.Photos'}, + @{Id=[guid]::NewGuid(); Name='Store'; Pub=$msPub; Prod='Microsoft.WindowsStore'}, + @{Id=[guid]::NewGuid(); Name='Wallet'; Pub=$msPub; Prod='Microsoft.Wallet'}, + @{Id=[guid]::NewGuid(); Name='Cortana'; Pub=$mwPub; Prod='Microsoft.Windows.Cortana'}, + @{Id=[guid]::NewGuid(); Name='Intel Graphics'; Pub='CN=EB51A5DA-0E72-4863-82E4-EA21C1F8DFE3'; Prod='AppUp.IntelGraphicsControlPanel'}, + @{Id=[guid]::NewGuid(); Name='Intel GFX Exp'; Pub='CN=EB51A5DA-0E72-4863-82E4-EA21C1F8DFE3'; Prod='AppUp.IntelGraphicsExperience'}, + @{Id=[guid]::NewGuid(); Name='Intel Optane'; Pub='CN=EB51A5DA-0E72-4863-82E4-EA21C1F8DFE3'; Prod='AppUp.IntelOptaneMemoryandStorageManagement'}, + @{Id=[guid]::NewGuid(); Name='Realtek Audio'; Pub='CN=83564403-0B26-46B8-9D84-040F43691D31'; Prod='RealtekSemiconductorCorp.RealtekAudioControl'} +) + +$denyRules = '' +foreach ($r in $denyList) { + $denyRules += @" + + + + + + + +"@ +} + +$xml = @" + + + + + + + + + +$denyRules + + + + + + +"@ + +# Save and apply +$xml | Out-File "C:\Windows\Temp\applocker-policy.xml" -Encoding UTF8 +Set-AppLockerPolicy -XmlPolicy "C:\Windows\Temp\applocker-policy.xml" +Write-Output "AppLocker policy applied with $($denyList.Count) Deny rules for SG-Caregivers" +Write-Output "Denied apps:" +$denyList | ForEach-Object { Write-Output " $($_.Name) ($($_.Prod))" } +# Verify +$current = Get-AppLockerPolicy -Local -Xml +Write-Output "" +Write-Output "Policy verified: $($current.Length) chars" diff --git a/clients/cascades-tucson/scripts/applocker-recheck-apps.ps1 b/clients/cascades-tucson/scripts/applocker-recheck-apps.ps1 new file mode 100644 index 00000000..ab4b743d --- /dev/null +++ b/clients/cascades-tucson/scripts/applocker-recheck-apps.ps1 @@ -0,0 +1,9 @@ +# Check what user-facing apps are actually available +$all = Get-AppxPackage -AllUsers -ErrorAction SilentlyContinue +$userFacing = $all | Where-Object { $_.Name -notmatch '^Microsoft\.(NET|VCLibs|UI\.Xaml|WindowsApp|Services|Advertising|Office\.(Actions|Push)|AAD|Account|Bio|Cred|Lock|Win32|WidgetsPlatform|AsyncText|ApplicationCompat|AIFabric|DesktopApp|StorePurchase|SecHealth|ECApp|HE[IV]|AV1|AVC|MPEG|Raw|VP9|Webp|Web[Mm]|M365|OneDrive|StartExp|MicrosoftEdge[^.]|Window\.CBS)' -and $_.Name -notmatch '^(Microsoft)?Windows\.' -and $_.Name -notmatch '^(aimgr|InputApp|NcsiUwpApp|MicrosoftWindows\.|MicrosoftCorporationII|KONICAMINOLTA|Windows\.)' -and $_.Name -notmatch '^[0-9a-f]{8}-' -and $_.Name -notmatch '^(E2A4F912|F46D4000|1527c705|c5e2524a)' -and $_.IsFramework -ne $true } +Write-Output "=== User-facing apps on this machine ===" +$userFacing | Sort-Object Name -Unique | ForEach-Object { + Write-Output "$($_.Name) | $($_.Publisher) | $($_.PackageFamilyName)" +} +Write-Output "" +Write-Output "Count: $($userFacing | Sort-Object Name -Unique | Measure-Object | Select-Object -ExpandProperty Count)" diff --git a/clients/cascades-tucson/scripts/applocker-stage.ps1 b/clients/cascades-tucson/scripts/applocker-stage.ps1 new file mode 100644 index 00000000..49f26218 --- /dev/null +++ b/clients/cascades-tucson/scripts/applocker-stage.ps1 @@ -0,0 +1,33 @@ +# Stage the AppLocker script on the endpoint +$script = @' +$cgSID = 'S-1-5-21-388235164-2207693853-3666415804-1183' +$evSID = 'S-1-1-0' +$msPub = 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US' +$mwPub = 'CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington, C=US' +$denyList = @( + @{Id='b1a1a1a1-1111-1111-1111-111111111101'; Name='Edge GameAssist'; Pub=$msPub; Prod='Microsoft.Edge.GameAssist'}, + @{Id='b1a1a1a1-1111-1111-1111-111111111102'; Name='Paint'; Pub=$msPub; Prod='Microsoft.MSPaint'}, + @{Id='b1a1a1a1-1111-1111-1111-111111111103'; Name='Photos'; Pub=$msPub; Prod='Microsoft.Windows.Photos'}, + @{Id='b1a1a1a1-1111-1111-1111-111111111104'; Name='Store'; Pub=$msPub; Prod='Microsoft.WindowsStore'}, + @{Id='b1a1a1a1-1111-1111-1111-111111111105'; Name='Wallet'; Pub=$msPub; Prod='Microsoft.Wallet'}, + @{Id='b1a1a1a1-1111-1111-1111-111111111106'; Name='Cortana'; Pub=$mwPub; Prod='Microsoft.Windows.Cortana'}, + @{Id='b1a1a1a1-1111-1111-1111-111111111107'; Name='Intel Graphics'; Pub='CN=EB51A5DA-0E72-4863-82E4-EA21C1F8DFE3'; Prod='AppUp.IntelGraphicsControlPanel'}, + @{Id='b1a1a1a1-1111-1111-1111-111111111108'; Name='Intel GFX Exp'; Pub='CN=EB51A5DA-0E72-4863-82E4-EA21C1F8DFE3'; Prod='AppUp.IntelGraphicsExperience'}, + @{Id='b1a1a1a1-1111-1111-1111-111111111109'; Name='Intel Optane'; Pub='CN=EB51A5DA-0E72-4863-82E4-EA21C1F8DFE3'; Prod='AppUp.IntelOptaneMemoryandStorageManagement'}, + @{Id='b1a1a1a1-1111-1111-1111-111111111110'; Name='Realtek Audio'; Pub='CN=83564403-0B26-46B8-9D84-040F43691D31'; Prod='RealtekSemiconductorCorp.RealtekAudioControl'} +) +$denyRules = '' +foreach ($r in $denyList) { + $denyRules += "`n" +} +$xml = "`n$denyRules" +$xml | Out-File "C:\ProgramData\ACG\applocker-policy.xml" -Encoding UTF8 +Set-AppLockerPolicy -XmlPolicy "C:\ProgramData\ACG\applocker-policy.xml" +Write-Output "AppLocker applied: $($denyList.Count) Deny rules for SG-Caregivers" +$denyList | ForEach-Object { Write-Output " Denied: $($_.Prod)" } +$v = Get-AppLockerPolicy -Local -Xml +Write-Output "Policy length: $($v.Length) chars" +'@ +New-Item -ItemType Directory -Path "C:\ProgramData\ACG" -Force | Out-Null +Set-Content "C:\ProgramData\ACG\apply-applocker.ps1" $script -Force +Write-Output "Staged script at C:\ProgramData\ACG\apply-applocker.ps1" diff --git a/clients/cascades-tucson/scripts/applocker-step1-enable.ps1 b/clients/cascades-tucson/scripts/applocker-step1-enable.ps1 new file mode 100644 index 00000000..3a20ecd0 --- /dev/null +++ b/clients/cascades-tucson/scripts/applocker-step1-enable.ps1 @@ -0,0 +1,28 @@ +# Step 1: Enable the Application Identity service (required for AppLocker) +Set-Service -Name AppIDSvc -StartupType Automatic +Start-Service -Name AppIDSvc -ErrorAction SilentlyContinue +$svc = Get-Service AppIDSvc +Write-Output "AppIDSvc: Status=$($svc.Status) StartType=$($svc.StartType)" + +# Get publisher info for apps we want to deny +$deny = @('4DF9E0F8.Netflix','Microsoft.WindowsCamera','Microsoft.GamingApp','Microsoft.XboxApp', +'Microsoft.XboxGameOverlay','Microsoft.XboxGamingOverlay','Microsoft.Xbox.TCUI', +'Microsoft.XboxIdentityProvider','Microsoft.XboxSpeechToTextOverlay','Microsoft.ZuneVideo', +'Microsoft.WindowsMaps','Microsoft.YourPhone','Microsoft.SkypeApp','Microsoft.People', +'Microsoft.Messaging','Microsoft.MixedReality.Portal','Microsoft.Microsoft3DViewer', +'Microsoft.Copilot','Microsoft.WindowsTerminal','Microsoft.Edge.GameAssist', +'Microsoft.Getstarted','Microsoft.OneConnect','Microsoft.Windows.Photos','Microsoft.MSPaint', +'Microsoft.Print3D','SpotifyAB.SpotifyMusic','Evernote.Evernote','C27EB4BA.DropboxOEM', +'7EE7776C.LinkedInforWindows','AcerIncorporated.AcerCareCenterS', +'AcerIncorporated.AcerCollectionS','AcerIncorporated.AcerRegistration') + +Write-Output "" +Write-Output "=== Publisher info for deny list ===" +foreach ($name in $deny) { + $pkg = Get-AppxPackage -AllUsers -Name $name -ErrorAction SilentlyContinue | Select-Object -First 1 + if ($pkg) { + Write-Output "$name|$($pkg.Publisher)|$($pkg.PackageFamilyName)" + } else { + Write-Output "$name|NOT_INSTALLED|" + } +} diff --git a/clients/cascades-tucson/scripts/applocker-to-gpo.ps1 b/clients/cascades-tucson/scripts/applocker-to-gpo.ps1 new file mode 100644 index 00000000..108c5676 --- /dev/null +++ b/clients/cascades-tucson/scripts/applocker-to-gpo.ps1 @@ -0,0 +1,22 @@ +Import-Module GroupPolicy +$gpoName = 'CSC - Caregiver Device Lockdown' +$xmlPath = "\\cascades.local\SYSVOL\cascades.local\scripts\applocker-caregiver.xml" +$xml = Get-Content $xmlPath -Raw +Set-AppLockerPolicy -XmlPolicy $xmlPath -Ldap "LDAP://$(([ADSI]'').distinguishedName)" -ErrorAction SilentlyContinue +# AppLocker GPO needs to be set via registry in the GPO +# HKLM\SOFTWARE\Policies\Microsoft\Windows\SrpV2\Appx +$gpo = Get-GPO -Name $gpoName +$base = 'HKLM\SOFTWARE\Policies\Microsoft\Windows\SrpV2\Appx' +Set-GPRegistryValue -Guid $gpo.Id -Key $base -ValueName 'EnforcementMode' -Type String -Value '1' | Out-Null +# Parse XML to extract individual rules +[xml]$doc = $xml +$rules = $doc.AppLockerPolicy.RuleCollection | Where-Object { $_.Type -eq 'Appx' } +foreach ($rule in $rules.FilePublisherRule) { + $ruleXml = $rule.OuterXml + Set-GPRegistryValue -Guid $gpo.Id -Key "$base\$($rule.Id)" -ValueName 'Value' -Type String -Value $ruleXml | Out-Null + Write-Output "GPO rule: $($rule.Name)" +} +Write-Output "AppLocker rules written to GPO: $gpoName" +# Enable AppIDSvc via GPO +Set-GPRegistryValue -Guid $gpo.Id -Key 'HKLM\SYSTEM\CurrentControlSet\Services\AppIDSvc' -ValueName 'Start' -Type DWord -Value 2 | Out-Null +Write-Output "AppIDSvc set to Automatic in GPO" diff --git a/clients/cascades-tucson/scripts/applocker-write-xml.ps1 b/clients/cascades-tucson/scripts/applocker-write-xml.ps1 new file mode 100644 index 00000000..7b1841dc --- /dev/null +++ b/clients/cascades-tucson/scripts/applocker-write-xml.ps1 @@ -0,0 +1,25 @@ +$cgSID = 'S-1-5-21-388235164-2207693853-3666415804-1183' +$evSID = 'S-1-1-0' +$ms = 'CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US' +$mw = 'CN=Microsoft Windows, O=Microsoft Corporation, L=Redmond, S=Washington, C=US' +$deny = @( + @('b1a10001','Edge GameAssist',$ms,'Microsoft.Edge.GameAssist'), + @('b1a10002','Paint',$ms,'Microsoft.MSPaint'), + @('b1a10003','Photos',$ms,'Microsoft.Windows.Photos'), + @('b1a10004','Store',$ms,'Microsoft.WindowsStore'), + @('b1a10005','Wallet',$ms,'Microsoft.Wallet'), + @('b1a10006','Cortana',$mw,'Microsoft.Windows.Cortana'), + @('b1a10007','Intel GFX','CN=EB51A5DA-0E72-4863-82E4-EA21C1F8DFE3','AppUp.IntelGraphicsControlPanel'), + @('b1a10008','Intel GFX2','CN=EB51A5DA-0E72-4863-82E4-EA21C1F8DFE3','AppUp.IntelGraphicsExperience'), + @('b1a10009','Intel Opt','CN=EB51A5DA-0E72-4863-82E4-EA21C1F8DFE3','AppUp.IntelOptaneMemoryandStorageManagement'), + @('b1a1000a','Realtek','CN=83564403-0B26-46B8-9D84-040F43691D31','RealtekSemiconductorCorp.RealtekAudioControl') +) +$r = '' +foreach ($d in $deny) { + $id = "$($d[0])-0000-0000-0000-000000000000" + $r += "" +} +$xml = "$r" +$path = "\\cascades.local\SYSVOL\cascades.local\scripts\applocker-caregiver.xml" +$xml | Out-File $path -Encoding UTF8 +Write-Output "Written: $path ($($xml.Length) chars, $($deny.Count) deny rules)" diff --git a/clients/cascades-tucson/scripts/build-applocker-policy.ps1 b/clients/cascades-tucson/scripts/build-applocker-policy.ps1 new file mode 100644 index 00000000..63869c1a --- /dev/null +++ b/clients/cascades-tucson/scripts/build-applocker-policy.ps1 @@ -0,0 +1,51 @@ +# Build and apply AppLocker policy via the Caregiver Device Lockdown GPO +# Packaged App Rules: Allow Everyone *, Deny SG-Caregivers specific apps +# Executable Rules: default 3 rules (Everyone: Windows, ProgramFiles; Admins: *) + +$cgSID = 'S-1-5-21-388235164-2207693853-3666415804-1183' +$evSID = 'S-1-1-0' +$adSID = 'S-1-5-32-544' + +# Apps to DENY for caregivers (user-facing, non-essential) +$denyApps = @( + @{Name='Netflix'; Publisher='CN=A278AB0D-5F3F-4AE5-8CFE-4F81D2D0B2CB'}, + @{Name='Microsoft.WindowsCamera'; Publisher='CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'}, + @{Name='Microsoft.GamingApp'; Publisher='CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'}, + @{Name='Microsoft.XboxApp'; Publisher='CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'}, + @{Name='Microsoft.XboxGameOverlay'; Publisher='CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'}, + @{Name='Microsoft.XboxGamingOverlay'; Publisher='CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'}, + @{Name='Microsoft.Xbox.TCUI'; Publisher='CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'}, + @{Name='Microsoft.XboxIdentityProvider'; Publisher='CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'}, + @{Name='Microsoft.XboxSpeechToTextOverlay'; Publisher='CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'}, + @{Name='Microsoft.ZuneVideo'; Publisher='CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'}, + @{Name='Microsoft.WindowsMaps'; Publisher='CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'}, + @{Name='Microsoft.YourPhone'; Publisher='CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'}, + @{Name='Microsoft.SkypeApp'; Publisher='CN=Skype Software Sarl, O=Microsoft Corporation, L=Luxembourg, S=Luxembourg, C=LU'}, + @{Name='Microsoft.People'; Publisher='CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'}, + @{Name='Microsoft.Messaging'; Publisher='CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'}, + @{Name='Microsoft.MixedReality.Portal'; Publisher='CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'}, + @{Name='Microsoft.Microsoft3DViewer'; Publisher='CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'}, + @{Name='Microsoft.Copilot'; Publisher='CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'}, + @{Name='Microsoft.WindowsTerminal'; Publisher='CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'}, + @{Name='Microsoft.Edge.GameAssist'; Publisher='CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'}, + @{Name='Microsoft.Getstarted'; Publisher='CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'}, + @{Name='Microsoft.OneConnect'; Publisher='CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'}, + @{Name='Microsoft.Windows.Photos'; Publisher='CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'}, + @{Name='Microsoft.MSPaint'; Publisher='CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'}, + @{Name='Microsoft.Print3D'; Publisher='CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US'} +) + +# Also deny third-party bloatware +$denyApps += @( + @{Name='SpotifyAB.SpotifyMusic'; Publisher='CN=453637B3-4178-46BE-A0F0-B84B10FAF303'}, + @{Name='Evernote.Evernote'; Publisher='CN=3F73DFD8-A32C-4D31-B9D8-9A5B42E1280D'}, + @{Name='C27EB4BA.DropboxOEM'; Publisher='CN=C27EB4BA-869B-4AD4-9872-5B562A3C3E11'}, + @{Name='7EE7776C.LinkedInforWindows'; Publisher='CN=7EE7776C-F189-4999-B4A0-0D96A4B4DC3E'}, + @{Name='AcerIncorporated.AcerCareCenterS'; Publisher='CN=Acer Incorporated, O=Acer Incorporated, L=Taipei, C=TW'}, + @{Name='AcerIncorporated.AcerCollectionS'; Publisher='CN=Acer Incorporated, O=Acer Incorporated, L=Taipei, C=TW'}, + @{Name='AcerIncorporated.AcerRegistration'; Publisher='CN=Acer Incorporated, O=Acer Incorporated, L=Taipei, C=TW'} +) + +Write-Output "Building AppLocker policy with $($denyApps.Count) Deny rules for SG-Caregivers..." +Write-Output "Deny list:" +$denyApps | ForEach-Object { Write-Output " $($_.Name)" } diff --git a/clients/cascades-tucson/scripts/get-applocker-sids.ps1 b/clients/cascades-tucson/scripts/get-applocker-sids.ps1 new file mode 100644 index 00000000..e7f41880 --- /dev/null +++ b/clients/cascades-tucson/scripts/get-applocker-sids.ps1 @@ -0,0 +1,9 @@ +Import-Module ActiveDirectory +$cg = Get-ADGroup 'SG-Caregivers' +Write-Output "SG-Caregivers SID: $($cg.SID)" +$du = Get-ADGroup 'Domain Users' +Write-Output "Domain Users SID: $($du.SID)" +$ba = New-Object System.Security.Principal.SecurityIdentifier('S-1-5-32-544') +Write-Output "BUILTIN\Administrators SID: $ba" +$everyone = New-Object System.Security.Principal.SecurityIdentifier('S-1-1-0') +Write-Output "Everyone SID: $everyone" diff --git a/clients/cascades-tucson/session-logs/2026-07/2026-07-17-howard-nurse-station-kiosk-build.md b/clients/cascades-tucson/session-logs/2026-07/2026-07-17-howard-nurse-station-kiosk-build.md index 25256388..6cb0c917 100644 --- a/clients/cascades-tucson/session-logs/2026-07/2026-07-17-howard-nurse-station-kiosk-build.md +++ b/clients/cascades-tucson/session-logs/2026-07/2026-07-17-howard-nurse-station-kiosk-build.md @@ -98,3 +98,47 @@ Session ended with app restriction still incomplete. The UI restrictions (no CMD - Caregiver controls doc: `clients/cascades-tucson/docs/security/hipaa-caregiver-controls.md` - ALIS SSO app: `d5108493-cba8-4f08-90b6-1bb0bc09eb2a` - Syncro customer 20149445; prepaid block 21.5 hrs (live 7/15) + +## Update: 14:34 PT — AppLocker app restriction completed + +### Session Summary + +Completed the app restriction for caregivers on NURSESTATION-PC using AppLocker, the built-in GPO-based application control. Howard directed that the solution must use proper domain tools (not hacks like app removal) so that non-caregiver users retain full access and the configuration survives machine replacement. + +AppLocker Packaged App Rules were built with an `Allow Everyone: *` baseline (all users get all apps by default) plus 10 Deny rules scoped to `SG-Caregivers` (SID `S-1-5-21-388235164-2207693853-3666415804-1183`) blocking non-essential user-facing apps: Edge GameAssist, Paint, Photos, Store, Wallet, Cortana, Intel Graphics/Experience/Optane, and Realtek Audio. The Executable/MSI/Script/DLL rule collections are set to `NotConfigured` (no restriction on Win32 apps — the existing UI restrictions via the kiosk GPO handle CMD/PowerShell/Settings/Control Panel/Run/Task Manager/Store blocking). + +The policy XML was written to `\\cascades.local\SYSVOL\cascades.local\scripts\applocker-caregiver.xml`, applied locally on NURSESTATION-PC via `Set-AppLockerPolicy`, and also written into the `CSC - Caregiver Device Lockdown` GPO (Computer Configuration, `HKLM\SOFTWARE\Policies\Microsoft\Windows\SrpV2\Appx`) with individual rules as registry values. The Application Identity service (`AppIDSvc`) was set to Automatic start both locally and via GPO. Howard confirmed the restrictions are working — blocked apps show the administrator block message for caregivers while non-caregivers are unaffected. + +### Key Decisions + +- AppLocker chosen over app removal because non-caregiver users need access to all apps and the config must survive machine replacement. AppLocker is the proper GPO-based tool for group-specific app whitelisting. +- Packaged App Rules only (not Executable Rules) — Win32 app access is controlled by the existing UI restrictions (DisableCMD, NoRun, NoControlPanel, etc.) in the kiosk GPO. AppLocker Executable Rules would affect all users on the machine and can't be scoped to a group without complex workarounds. +- `Allow Everyone: *` + `Deny SG-Caregivers: [specific apps]` pattern — the only AppLocker approach that restricts one group while leaving everyone else unrestricted. Deny rules override Allow rules, so caregivers are blocked from the listed apps despite the baseline Allow. +- Most bloatware (Netflix, Xbox, Camera, Spotify, etc.) was already absent from the machine — the deny list focused on what was actually installed. +- Confirmed caregiver accounts are standard domain users (not admin) — no local admin, no Domain Admins membership, only SG-Caregivers group membership. + +### Problems Encountered + +- RMM agent body-size limit (~7KB encoded) repeatedly hit when building AppLocker XML inline in PowerShell scripts. Resolved by writing the XML generation script to SYSVOL on CS-SERVER first, then applying from NURSESTATION-PC with a simple one-liner referencing the SYSVOL path. +- Initial `Get-AppxPackage -AllUsers -Name $name` returned NOT_INSTALLED for most apps despite earlier full listing showing them — likely a timing issue with package registration state after profile operations. Re-enumerated with a filtered full listing to get accurate installed app inventory. + +### Configuration Changes + +- `\\cascades.local\SYSVOL\cascades.local\scripts\applocker-caregiver.xml` — NEW: AppLocker policy XML (5282 chars, 11 rules: 1 Allow Everyone + 10 Deny SG-Caregivers) +- GPO `CSC - Caregiver Device Lockdown`: AppLocker Appx rules added (HKLM\SOFTWARE\Policies\Microsoft\Windows\SrpV2\Appx), AppIDSvc Start=2 (Automatic) +- NURSESTATION-PC: AppIDSvc enabled and running, AppLocker local policy applied +- Local scripts created: `applocker-step1-enable.ps1`, `applocker-recheck-apps.ps1`, `applocker-apply-simple.ps1`, `applocker-write-xml.ps1`, `applocker-to-gpo.ps1`, `applocker-stage.ps1`, `build-applocker-policy.ps1`, `get-applocker-sids.ps1` + +### Infrastructure + +- SG-Caregivers SID: `S-1-5-21-388235164-2207693853-3666415804-1183` +- Domain Users SID: `S-1-5-21-388235164-2207693853-3666415804-513` +- AppLocker policy path: `\\cascades.local\SYSVOL\cascades.local\scripts\applocker-caregiver.xml` +- GPO: `CSC - Caregiver Device Lockdown`, AppLocker rules in `HKLM\SOFTWARE\Policies\Microsoft\Windows\SrpV2\Appx` + +### Pending / Incomplete Tasks + +1. **ASSISTNURSE-PC:** Move from CN=Computers to OU=Caregiver Devices + deploy machine-level printers + gpupdate. All GPO settings (kiosk Edge policies, shortcuts, AppLocker, UI restrictions, DontDisplayLastUserName) apply automatically via OU membership. +2. **Test as non-caregiver:** Verify Howard's own login is completely unrestricted (no AppLocker blocks, no UI restrictions, full Start menu). +3. **PRT/SSO verification:** Confirm ALIS SSO is fully silent after the PRT cache clear + reboot. +4. **Remaining roadmap items carried forward from earlier session.**