sync: auto-sync from HOWARD-HOME at 2026-07-17 14:14:41

Author: Howard Enos
Machine: HOWARD-HOME
Timestamp: 2026-07-17 14:14:41
This commit is contained in:
2026-07-17 14:15:18 -07:00
parent 3a7b6a1cc1
commit 8d2ca14cac
47 changed files with 1025 additions and 0 deletions

1
.mhs.json Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,21 @@
# Add the nurse printer as a machine-level connection via Point and Print
# This makes it available to ALL users who log in
$printer = '\\CS-SERVER\Nurses - Brother MFC-L8900CDW'
# Check if already installed as local/machine printer
$existing = Get-Printer -Name $printer -ErrorAction SilentlyContinue
if ($existing -and $existing.Type -eq 'Local') {
Write-Output "Already installed as machine printer: $printer"
} else {
# Use rundll32 to install as machine-level
& rundll32 printui.dll,PrintUIEntry /ga /n $printer 2>&1
Write-Output "Added machine-level printer connection: $printer"
}
# Set as default for the machine
# Also add the Health Services printer the same way
$printer2 = '\\CS-SERVER\Health Services - Konica Minolta C368'
& rundll32 printui.dll,PrintUIEntry /ga /n $printer2 2>&1
Write-Output "Added machine-level printer connection: $printer2"
Write-Output ""
Write-Output "Both printers will be available to all users on next login."
Write-Output "Current printers:"
Get-Printer | Select-Object Name, Type | Format-Table -AutoSize

View File

@@ -0,0 +1,9 @@
Import-Module ActiveDirectory
$u = Get-ADUser 'test.caregiver' -Properties mail
Set-ADUser $u -UserPrincipalName 'pilot.test@cascadestucson.com' -EmailAddress 'pilot.test@cascadestucson.com' -SamAccountName 'pilot.test'
Rename-ADObject -Identity $u.DistinguishedName -NewName 'Pilot Test (Caregiver)'
$v = Get-ADUser 'pilot.test' -Properties mail, MemberOf
Write-Output "sAM: $($v.SamAccountName) UPN: $($v.UserPrincipalName) mail: $($v.mail)"
Write-Output "DN: $($v.DistinguishedName)"
Write-Output "Groups: $($v.MemberOf -join '; ')"
try { Import-Module ADSync -ErrorAction Stop; Start-ADSyncSyncCycle -PolicyType Delta | Out-Null; Write-Output 'Delta sync started' } catch { Write-Output "Delta sync skipped: $_" }

View File

@@ -0,0 +1,11 @@
Import-Module GroupPolicy
$gpo = 'CSC - Nurse Station Kiosk'
$hkcu = 'HKCU\Software\Policies\Microsoft\Windows'
Set-GPRegistryValue -Name $gpo -Key "$hkcu\Explorer" -ValueName 'NoRun' -Type DWord -Value 1 | Out-Null
Set-GPRegistryValue -Name $gpo -Key "$hkcu\Explorer" -ValueName 'NoSetFolders' -Type DWord -Value 1 | Out-Null
Set-GPRegistryValue -Name $gpo -Key "$hkcu\Explorer" -ValueName 'NoSMHelp' -Type DWord -Value 1 | Out-Null
Set-GPRegistryValue -Name $gpo -Key "$hkcu\Explorer" -ValueName 'NoRecentDocsHistory' -Type DWord -Value 1 | Out-Null
Set-GPRegistryValue -Name $gpo -Key "$hkcu\Explorer" -ValueName 'ClearRecentDocsOnExit' -Type DWord -Value 1 | Out-Null
Set-GPRegistryValue -Name $gpo -Key "$hkcu\Explorer" -ValueName 'NoControlPanel' -Type DWord -Value 1 | Out-Null
Set-GPRegistryValue -Name $gpo -Key "$hkcu\Explorer" -ValueName 'NoNetHood' -Type DWord -Value 1 | Out-Null
Write-Output "Part 1 done: Start menu + Explorer restrictions"

View File

@@ -0,0 +1,7 @@
Import-Module GroupPolicy
$gpo = 'CSC - Nurse Station Kiosk'
Set-GPRegistryValue -Name $gpo -Key 'HKCU\Software\Policies\Microsoft\Windows\System' -ValueName 'DisableCMD' -Type DWord -Value 1 | Out-Null
Set-GPRegistryValue -Name $gpo -Key 'HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System' -ValueName 'DisableRegistryTools' -Type DWord -Value 1 | Out-Null
Set-GPRegistryValue -Name $gpo -Key 'HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System' -ValueName 'DisableTaskMgr' -Type DWord -Value 1 | Out-Null
Set-GPRegistryValue -Name $gpo -Key 'HKCU\Software\Policies\Microsoft\Windows\Installer' -ValueName 'DisableUserInstalls' -Type DWord -Value 1 | Out-Null
Write-Output "Part 2 done: CMD/regedit/taskmgr/installer blocked"

View File

@@ -0,0 +1,13 @@
Import-Module ActiveDirectory
foreach ($sam in 'test.caregiver','pilot.test') {
$u = Get-ADUser -Filter "SamAccountName -eq '$sam'" -Properties mail, MemberOf, Enabled, whenCreated, Description
if ($u) {
Write-Output "=== $sam ==="
Write-Output "DN: $($u.DistinguishedName)"
Write-Output "UPN: $($u.UserPrincipalName) mail: $($u.mail) enabled: $($u.Enabled) created: $($u.whenCreated)"
Write-Output "Desc: $($u.Description)"
Write-Output "Groups: $($u.MemberOf -join '; ')"
} else { Write-Output "=== $sam : NOT FOUND ===" }
}
$dup = Get-ADUser -Filter "UserPrincipalName -eq 'pilot.test@cascadestucson.com'" | Measure-Object
Write-Output "Users with UPN pilot.test@cascadestucson.com: $($dup.Count)"

View File

@@ -0,0 +1,49 @@
Import-Module GroupPolicy
$gpo = 'CSC - Nurse Station Kiosk'
$hkcu = 'HKCU\Software\Policies\Microsoft\Windows'
# --- Start Menu / Taskbar restrictions ---
# Remove Run from Start Menu
Set-GPRegistryValue -Name $gpo -Key "$hkcu\Explorer" -ValueName 'NoRun' -Type DWord -Value 1 | Out-Null
# Remove Search from taskbar
Set-GPRegistryValue -Name $gpo -Key "$hkcu\Explorer" -ValueName 'DisableSearchBoxSuggestions' -Type DWord -Value 1 | Out-Null
# Remove Settings from Start
Set-GPRegistryValue -Name $gpo -Key "$hkcu\Explorer" -ValueName 'NoSetFolders' -Type DWord -Value 1 | Out-Null
# Remove Help
Set-GPRegistryValue -Name $gpo -Key "$hkcu\Explorer" -ValueName 'NoSMHelp' -Type DWord -Value 1 | Out-Null
# Don't keep history of recently opened documents
Set-GPRegistryValue -Name $gpo -Key "$hkcu\Explorer" -ValueName 'NoRecentDocsHistory' -Type DWord -Value 1 | Out-Null
Set-GPRegistryValue -Name $gpo -Key "$hkcu\Explorer" -ValueName 'ClearRecentDocsOnExit' -Type DWord -Value 1 | Out-Null
Write-Output "Start Menu restrictions set"
# --- Block command prompt and PowerShell ---
Set-GPRegistryValue -Name $gpo -Key 'HKCU\Software\Policies\Microsoft\Windows\System' -ValueName 'DisableCMD' -Type DWord -Value 1 | Out-Null
# Block access to registry editor
Set-GPRegistryValue -Name $gpo -Key 'HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System' -ValueName 'DisableRegistryTools' -Type DWord -Value 1 | Out-Null
# Block Task Manager
Set-GPRegistryValue -Name $gpo -Key 'HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System' -ValueName 'DisableTaskMgr' -Type DWord -Value 1 | Out-Null
Write-Output "CMD/regedit/taskmgr blocked"
# --- Restrict Control Panel ---
Set-GPRegistryValue -Name $gpo -Key "$hkcu\Explorer" -ValueName 'NoControlPanel' -Type DWord -Value 1 | Out-Null
Write-Output "Control Panel blocked"
# --- File Explorer restrictions ---
# Hide drives in My Computer (don't block access, just hide)
# Remove File Explorer from taskbar pinning isn't needed - just restrict what they see
# Prevent access to drives from My Computer - but allow printing and Office file access
# Remove Network from navigation pane
Set-GPRegistryValue -Name $gpo -Key "$hkcu\Explorer" -ValueName 'NoNetHood' -Type DWord -Value 1 | Out-Null
Write-Output "Explorer restrictions set"
# --- Prevent installing apps ---
Set-GPRegistryValue -Name $gpo -Key 'HKCU\Software\Policies\Microsoft\Windows\Installer' -ValueName 'DisableUserInstalls' -Type DWord -Value 1 | Out-Null
Write-Output "App install blocked"
Write-Output ""
Write-Output "Done. Caregivers can use: Edge, Office apps, Teams, printers."
Write-Output "Blocked: CMD, PowerShell, regedit, Task Manager, Control Panel, Run, Settings, app installs."

View File

@@ -0,0 +1,15 @@
Import-Module ActiveDirectory
$u = Get-ADUser 'a.vallejo' -Properties MemberOf, Enabled, PasswordLastSet, LockedOut, PasswordExpired
Write-Output "Enabled: $($u.Enabled) LockedOut: $($u.LockedOut) PwExpired: $($u.PasswordExpired)"
Write-Output "PwLastSet: $($u.PasswordLastSet)"
Write-Output "UPN: $($u.UserPrincipalName)"
Write-Output "Groups:"
$u.MemberOf | ForEach-Object { Write-Output " $_" }
# Check if ChangePasswordAtLogon is set (would block login)
$raw = Get-ADUser 'a.vallejo' -Properties pwdLastSet
if ($raw.pwdLastSet -eq 0) { Write-Output "WARNING: ChangePasswordAtLogon=TRUE (pwdLastSet=0)" }
# Validate credential against DC
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$ctx = New-Object System.DirectoryServices.AccountManagement.PrincipalContext([System.DirectoryServices.AccountManagement.ContextType]::Domain, "cascades.local")
$valid = $ctx.ValidateCredentials("a.vallejo", "Sunrise4827")
Write-Output "Password validates: $valid"

View File

@@ -0,0 +1,23 @@
# Check what GP CSEs are registered on this machine
Write-Output "=== Shortcuts CSE registered? ==="
$shortcutCSE = Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions\{BC75B1ED-5833-4858-9BB8-CBF0B166DF9D}" -ErrorAction SilentlyContinue
if ($shortcutCSE) {
Write-Output "YES: $($shortcutCSE.'(default)') DLL: $($shortcutCSE.DllName)"
} else { Write-Output "NOT REGISTERED" }
Write-Output ""
Write-Output "=== All GP Preference CSEs ==="
Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions" | ForEach-Object {
$p = Get-ItemProperty $_.PSPath -ErrorAction SilentlyContinue
$name = $p.'(default)'
if ($name -match 'Preference|Shortcut|File|Folder') {
Write-Output " $($_.PSChildName): $name"
}
}
Write-Output ""
Write-Output "=== Full GP event log (last 30, user policy) ==="
Get-WinEvent -LogName "Microsoft-Windows-GroupPolicy/Operational" -MaxEvents 30 -ErrorAction SilentlyContinue | Where-Object { $_.Message -match 'user|User|loopback|Kiosk|Nurse|failed|error|Extension' -and $_.Level -le 3 } | ForEach-Object {
Write-Output "$($_.TimeCreated) [id=$($_.Id) lvl=$($_.Level)]"
Write-Output " $($_.Message.Substring(0,[Math]::Min(250,$_.Message.Length)))"
}

View File

@@ -0,0 +1,12 @@
# Check if GPP shortcuts applied
Write-Output "=== Public Desktop ==="
Get-ChildItem "C:\Users\Public\Desktop\*" -ErrorAction SilentlyContinue | ForEach-Object { Write-Output " $($_.Name)" }
Write-Output "=== a.vallejo Desktop ==="
Get-ChildItem "C:\Users\a.vallejo\Desktop\*" -ErrorAction SilentlyContinue | ForEach-Object { Write-Output " $($_.Name)" }
Write-Output ""
Write-Output "=== GPResult for a.vallejo - applied GPOs ==="
gpresult /scope user /r 2>&1 | Select-String "CSC|Caregiver|Kiosk|Nurse|Shortcut|DENIED|filtering"
Write-Output ""
Write-Output "=== CSE Extensions registered ==="
$gptIni = Get-Content "\\cascades.local\SYSVOL\cascades.local\Policies\{3B5CD9A6-A278-4676-A9FD-9396D21A8261}\GPT.INI" -Raw
Write-Output $gptIni

View File

@@ -0,0 +1,6 @@
gpupdate /force /wait:60 | Out-Null
Write-Output '--- dsregcmd device state ---'
$d = dsregcmd /status
$d | Select-String 'AzureAdJoined|DomainJoined|DeviceId|TenantName|EnterpriseJoined' | ForEach-Object { $_.Line.Trim() }
Write-Output '--- SSO state ---'
$d | Select-String 'AzureAdPrt\s|OnPremTgt|CloudTgt' | ForEach-Object { $_.Line.Trim() }

View File

@@ -0,0 +1,9 @@
Write-Output "=== Printers on NURSESTATION-PC ==="
Get-Printer | Select-Object Name, PortName, Shared, Type | Format-Table -AutoSize
Write-Output ""
Write-Output "=== Print shares on CS-SERVER ==="
Get-ChildItem "\\CS-SERVER\*" -ErrorAction SilentlyContinue | ForEach-Object { Write-Output " $($_.Name)" }
Write-Output ""
Write-Output "=== Shared printers on CS-SERVER ==="
$printers = Get-WmiObject Win32_Printer -ComputerName CS-SERVER -ErrorAction SilentlyContinue | Where-Object { $_.Shared -eq $true }
$printers | ForEach-Object { Write-Output " $($_.Name) -> $($_.ShareName) [Port: $($_.PortName)] Location: $($_.Location)" }

View File

@@ -0,0 +1,15 @@
# Remove manually placed shortcuts (GPO replaces them)
foreach ($f in 'ALIS.url','Helpany.url','PharmCare.url','LinkRx.url') {
Remove-Item "C:\Users\Public\Desktop\$f" -Force -ErrorAction SilentlyContinue
Get-ChildItem "C:\Users" -Directory | Where-Object { $_.Name -notin 'Public','Default','Default User','All Users' } | ForEach-Object {
Remove-Item (Join-Path $_.FullName "Desktop\$f") -Force -ErrorAction SilentlyContinue
}
}
Write-Output "Cleaned all manual shortcuts"
gpupdate /force /wait:60 2>&1 | Out-Null
Write-Output "gpupdate done"
# Check result
Write-Output "=== Public Desktop ==="
Get-ChildItem "C:\Users\Public\Desktop\*" -ErrorAction SilentlyContinue | ForEach-Object { Write-Output " $($_.Name)" }
Write-Output "=== pilot.test Desktop ==="
Get-ChildItem "C:\Users\pilot.test\Desktop\*" -ErrorAction SilentlyContinue | ForEach-Object { Write-Output " $($_.Name)" }

View File

@@ -0,0 +1,13 @@
# Remove stale Edge profile data for the current pilot.test user
$edgePath = "C:\Users\pilot.test\AppData\Local\Microsoft\Edge\User Data"
if (Test-Path $edgePath) {
# Kill Edge first
Get-Process msedge -ErrorAction SilentlyContinue | Stop-Process -Force
Start-Sleep -Seconds 2
Remove-Item $edgePath -Recurse -Force -ErrorAction SilentlyContinue
Write-Output "Cleared Edge profile data for pilot.test"
} else {
Write-Output "No Edge profile data for pilot.test"
}
gpupdate /force /wait:60 2>&1 | Out-Null
Write-Output "gpupdate done"

View File

@@ -0,0 +1,20 @@
Write-Output "=== Clearing stale token broker cache ==="
$aadBroker = Get-ChildItem "C:\Users\*\AppData\Local\Packages\Microsoft.AAD.BrokerPlugin_cw5n1h2txyewy" -Directory -ErrorAction SilentlyContinue
foreach ($p in $aadBroker) {
$ac = Join-Path $p.FullName "AC\TokenBroker"
if (Test-Path $ac) {
Remove-Item "$ac\*" -Recurse -Force -ErrorAction SilentlyContinue
Write-Output "Cleared: $ac"
}
}
$msAccount = Get-ChildItem "C:\Users\*\AppData\Local\Packages\Microsoft.Windows.CloudExperienceHost_cw5n1h2txyewy" -Directory -ErrorAction SilentlyContinue
foreach ($p in $msAccount) {
$ac = Join-Path $p.FullName "AC\TokenBroker"
if (Test-Path $ac) {
Remove-Item "$ac\*" -Recurse -Force -ErrorAction SilentlyContinue
Write-Output "Cleared: $ac"
}
}
Write-Output ""
Write-Output "Cache cleared. Reboot the machine, then log in as cascades\pilot.test."
Write-Output "The fresh login should acquire a PRT and Edge will SSO into ALIS automatically."

View File

@@ -0,0 +1,20 @@
Import-Module ActiveDirectory
$sam = 'test.caregiver'
$existing = Get-ADUser -Filter "SamAccountName -eq '$sam'" -ErrorAction SilentlyContinue
if ($existing) { Write-Output "EXISTS: $($existing.DistinguishedName)"; exit 0 }
# Place it in the same OU as an existing caregiver
$member = Get-ADGroupMember 'SG-Caregivers' | Where-Object objectClass -eq 'user' | Select-Object -First 1
$refUser = Get-ADUser $member.SamAccountName
$ou = ($refUser.DistinguishedName -split ',',2)[1]
Write-Output "Target OU: $ou"
$pw = ConvertTo-SecureString 'KioskTest-7492!' -AsPlainText -Force
New-ADUser -Name 'Test Caregiver' -GivenName 'Test' -Surname 'Caregiver' `
-SamAccountName $sam -UserPrincipalName 'test.caregiver@cascadestucson.com' `
-Path $ou -AccountPassword $pw -Enabled $true -ChangePasswordAtLogon $false `
-Description 'ACG kiosk pilot test account - remove after WS3 go-live'
Add-ADGroupMember -Identity 'SG-Caregivers' -Members $sam
Start-Sleep -Seconds 3
$u = Get-ADUser $sam -Properties MemberOf
Write-Output "CREATED: $($u.DistinguishedName)"
Write-Output "Groups: $($u.MemberOf -join '; ')"
try { Import-Module ADSync -ErrorAction Stop; Start-ADSyncSyncCycle -PolicyType Delta | Out-Null; Write-Output 'Delta sync started' } catch { Write-Output "Delta sync skipped: $_" }

View File

@@ -0,0 +1,10 @@
Write-Output "=== Recent GP events mentioning Preferences/Shortcut/CSE ==="
Get-WinEvent -LogName "Microsoft-Windows-GroupPolicy/Operational" -MaxEvents 100 -ErrorAction SilentlyContinue | Where-Object { $_.Message -match 'Shortcut|Preference|Extension|loopback|Nurse|Kiosk' } | Select-Object -First 20 | ForEach-Object { Write-Output "$($_.TimeCreated) [id=$($_.Id) lvl=$($_.Level)] $($_.Message.Substring(0,[Math]::Min(300,$_.Message.Length)))"; Write-Output "---" }
Write-Output ""
Write-Output "=== Verify Shortcuts.xml in kiosk GPO SYSVOL ==="
$kioskGuid = (Get-GPO -Name 'CSC - Nurse Station Kiosk').Id
$xmlPath = "\\cascades.local\SYSVOL\cascades.local\Policies\{$kioskGuid}\User\Preferences\Shortcuts\Shortcuts.xml"
if (Test-Path $xmlPath) {
Write-Output "EXISTS: $xmlPath"
Get-Content $xmlPath -Raw | Write-Output
} else { Write-Output "MISSING: $xmlPath" }

View File

@@ -0,0 +1,14 @@
# Run as the logged-in user to see what GPOs apply to THEM
Write-Output "=== Who am I ==="
whoami
Write-Output ""
Write-Output "=== User GPO results ==="
gpresult /scope user /r 2>&1
Write-Output ""
Write-Output "=== User desktop contents ==="
$desk = [Environment]::GetFolderPath("Desktop")
Write-Output "Desktop path: $desk"
Get-ChildItem "$desk\*" -ErrorAction SilentlyContinue | ForEach-Object { Write-Output " $($_.Name)" }
Write-Output ""
Write-Output "=== Event log: GP Preferences ==="
Get-WinEvent -LogName "Microsoft-Windows-GroupPolicy/Operational" -MaxEvents 20 -ErrorAction SilentlyContinue | Where-Object { $_.Message -match 'Shortcut|Preference|CSE|Extension' } | ForEach-Object { Write-Output "$($_.TimeCreated) [$($_.Id)] $($_.Message.Substring(0,[Math]::Min(200,$_.Message.Length)))" }

View File

@@ -0,0 +1,33 @@
# Clean shortcuts from Default profile (stops future new users getting dupes)
Remove-Item "C:\Users\Default\Desktop\ALIS.url" -Force -ErrorAction SilentlyContinue
Remove-Item "C:\Users\Default\Desktop\LinkRx.url" -Force -ErrorAction SilentlyContinue
Remove-Item "C:\Users\Default\Desktop\Helpany.url" -Force -ErrorAction SilentlyContinue
Remove-Item "C:\Users\Default\Desktop\PharmCare.url" -Force -ErrorAction SilentlyContinue
Write-Output "Cleaned Default profile desktop"
# Clean pilot.test per-user desktop
Remove-Item "C:\Users\pilot.test\Desktop\ALIS.url" -Force -ErrorAction SilentlyContinue
Remove-Item "C:\Users\pilot.test\Desktop\LinkRx.url" -Force -ErrorAction SilentlyContinue
Remove-Item "C:\Users\pilot.test\Desktop\Helpany.url" -Force -ErrorAction SilentlyContinue
Remove-Item "C:\Users\pilot.test\Desktop\PharmCare.url" -Force -ErrorAction SilentlyContinue
Write-Output "Cleaned pilot.test desktop"
# Clean any other user desktops that might have copies
Get-ChildItem "C:\Users" -Directory | Where-Object { $_.Name -notin 'Public','Default','Default User','All Users' } | ForEach-Object {
$desk = Join-Path $_.FullName "Desktop"
$removed = 0
foreach ($f in 'ALIS.url','Helpany.url','PharmCare.url','LinkRx.url') {
$p = Join-Path $desk $f
if (Test-Path $p) { Remove-Item $p -Force; $removed++ }
}
if ($removed -gt 0) { Write-Output "Cleaned $removed shortcuts from $($_.Name)" }
}
# Verify
Write-Output ""
Write-Output "=== Public Desktop (canonical, all users see these) ==="
Get-ChildItem "C:\Users\Public\Desktop\*" | ForEach-Object { Write-Output " $($_.Name)" }
Write-Output "=== Default Desktop (empty now) ==="
Get-ChildItem "C:\Users\Default\Desktop\*" -ErrorAction SilentlyContinue | ForEach-Object { Write-Output " $($_.Name)" }
Write-Output "=== pilot.test Desktop ==="
Get-ChildItem "C:\Users\pilot.test\Desktop\*" -ErrorAction SilentlyContinue | ForEach-Object { Write-Output " $($_.Name)" }

View File

@@ -0,0 +1,24 @@
# Check every possible shortcut location
Write-Output "=== C:\Users\Public\Desktop ==="
Get-ChildItem "C:\Users\Public\Desktop\*" | ForEach-Object { Write-Output " $($_.Name) [$($_.FullName)]" }
Write-Output ""
Write-Output "=== C:\Users\pilot.test\Desktop ==="
Get-ChildItem "C:\Users\pilot.test\Desktop\*" | ForEach-Object { Write-Output " $($_.Name) [$($_.FullName)]" }
Write-Output ""
Write-Output "=== C:\Users\Default\Desktop ==="
Get-ChildItem "C:\Users\Default\Desktop\*" -ErrorAction SilentlyContinue | ForEach-Object { Write-Output " $($_.Name) [$($_.FullName)]" }
Write-Output ""
Write-Output "=== All Users profile Desktop ==="
$allUsers = [Environment]::GetFolderPath("CommonDesktopDirectory")
Write-Output " Path: $allUsers"
Get-ChildItem "$allUsers\*" | ForEach-Object { Write-Output " $($_.Name) [$($_.FullName)]" }
Write-Output ""
Write-Output "=== pilot.test shell:desktop (resolved) ==="
$shell = "C:\Users\pilot.test\AppData\Roaming\Microsoft\Windows\Desktop"
if (Test-Path $shell) { Get-ChildItem "$shell\*" | ForEach-Object { Write-Output " $($_.Name)" } } else { Write-Output " (not present)" }
Write-Output ""
Write-Output "=== OneDrive Desktop redirect? ==="
$od = Get-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" -ErrorAction SilentlyContinue
if ($od) { Write-Output " Desktop = $($od.Desktop)" }
$odSys = Get-ItemProperty "Registry::HKEY_USERS\*\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" -Name Desktop -ErrorAction SilentlyContinue
$odSys | ForEach-Object { Write-Output " HKU Desktop = $($_.Desktop) [$($_.PSPath)]" }

View File

@@ -0,0 +1,16 @@
# Check SYSVOL for GPP Shortcuts/Files XML and any scripts referencing our URLs
$sysvol = "\\cascades.local\SYSVOL\cascades.local\Policies"
Write-Output "=== GPP XML files ==="
Get-ChildItem $sysvol -Recurse -Include "Shortcuts.xml","Files.xml" -ErrorAction SilentlyContinue | ForEach-Object {
Write-Output " $($_.FullName)"
Get-Content $_.FullName -Raw
}
Write-Output ""
Write-Output "=== Scripts referencing shortcuts ==="
Get-ChildItem $sysvol -Recurse -Include *.ps1,*.bat,*.cmd,*.vbs -ErrorAction SilentlyContinue | ForEach-Object {
$c = Get-Content $_.FullName -Raw -ErrorAction SilentlyContinue
if ($c -match 'alis|helpany|pharmcare|linkrx|\.url') {
Write-Output "MATCH: $($_.FullName)"
Write-Output $c
}
}

View File

@@ -0,0 +1,52 @@
# 1. Check GPO shortcut preferences (GP Preferences > Shortcuts)
Write-Output "=== GPO Results: Shortcut Preferences ==="
$gpResults = gpresult /scope user /xml 2>$null
if ($gpResults) {
$xml = [xml]$gpResults
# Look for shortcut extensions
$ns = @{gp='http://www.microsoft.com/GroupPolicy/Settings/Shortcuts'}
$shortcuts = $xml.SelectNodes('//gp:Shortcut', $ns)
if ($shortcuts.Count -gt 0) {
foreach ($s in $shortcuts) { Write-Output " GPP Shortcut: $($s.OuterXml.Substring(0, [Math]::Min(300, $s.OuterXml.Length)))" }
} else { Write-Output " No GPP shortcuts found in XML" }
# Also check for file preferences
$ns2 = @{gp='http://www.microsoft.com/GroupPolicy/Settings/Files'}
$files = $xml.SelectNodes('//gp:FileSetting', $ns2)
if ($files.Count -gt 0) {
foreach ($f in $files) { Write-Output " GPP File: $($f.OuterXml.Substring(0, [Math]::Min(300, $f.OuterXml.Length)))" }
}
}
# 2. Check logon scripts in GPO
Write-Output ""
Write-Output "=== Logon Scripts (GPO) ==="
$scripts = Get-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Logon\*\*" -ErrorAction SilentlyContinue
if ($scripts) { $scripts | ForEach-Object { Write-Output " Script: $($_.Script) Params: $($_.Parameters)" } } else { Write-Output " None" }
# 3. Check SYSVOL for any scripts referencing our URLs
Write-Output ""
Write-Output "=== SYSVOL scripts mentioning ALIS/Helpany/PharmCare/LinkRx ==="
$sysvol = "\\cascades.local\SYSVOL\cascades.local"
Get-ChildItem "$sysvol\Policies" -Recurse -Include *.ps1,*.bat,*.cmd,*.vbs -ErrorAction SilentlyContinue | ForEach-Object {
$content = Get-Content $_.FullName -Raw -ErrorAction SilentlyContinue
if ($content -match 'alis|helpany|pharmcare|linkrx|\.url') {
Write-Output " MATCH: $($_.FullName)"
}
}
# 4. Check GP Preferences XML in SYSVOL for shortcut/file items
Get-ChildItem "$sysvol\Policies" -Recurse -Include "Shortcuts.xml","Files.xml","Drives.xml" -ErrorAction SilentlyContinue | ForEach-Object {
Write-Output " GPP XML: $($_.FullName)"
$c = Get-Content $_.FullName -Raw
if ($c -match 'alis|helpany|pharmcare|linkrx|\.url') { Write-Output " -> contains shortcut references" }
}
# 5. Check scheduled tasks
Write-Output ""
Write-Output "=== Scheduled tasks mentioning shortcuts ==="
Get-ScheduledTask | Where-Object { $_.Actions.Execute -match 'shortcut|url|alis|helpany|pharmcare' -or $_.TaskName -match 'shortcut|desktop' } | ForEach-Object { Write-Output " Task: $($_.TaskName) -> $($_.Actions.Execute)" }
# 6. Check ActiveSetup
Write-Output ""
Write-Output "=== Active Setup (per-user on first login) ==="
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\*" -ErrorAction SilentlyContinue | Where-Object { $_.StubPath -match 'url|shortcut|alis|helpany|pharmcare|linkrx|desktop' } | ForEach-Object { Write-Output " $($_.PSChildName): $($_.StubPath)" }

View File

@@ -0,0 +1,19 @@
Import-Module GroupPolicy
$guid = '32d76052-4d92-446c-95fb-614653f84742'
# Remove the logon script (causing CMD popup) - GPP shortcuts work now
$scriptsDir = "\\cascades.local\SYSVOL\cascades.local\Policies\{$guid}\User\Scripts"
if (Test-Path $scriptsDir) { Remove-Item $scriptsDir -Recurse -Force; Write-Output "Removed Scripts dir" }
# Remove the script registry entries from kiosk GPO
$base = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Logon\0'
Remove-GPRegistryValue -Guid $guid -Key "$base\0" -ValueName 'Script' -ErrorAction SilentlyContinue
Remove-GPRegistryValue -Guid $guid -Key "$base\0" -ValueName 'Parameters' -ErrorAction SilentlyContinue
Remove-GPRegistryValue -Guid $guid -Key "$base\0" -ValueName 'IsPowershell' -ErrorAction SilentlyContinue
Remove-GPRegistryValue -Guid $guid -Key "$base" -ValueName 'GPO-ID' -ErrorAction SilentlyContinue
Remove-GPRegistryValue -Guid $guid -Key "$base" -ValueName 'SOM-ID' -ErrorAction SilentlyContinue
Remove-GPRegistryValue -Guid $guid -Key "$base" -ValueName 'FileSysPath' -ErrorAction SilentlyContinue
Remove-GPRegistryValue -Guid $guid -Key "$base" -ValueName 'DisplayName' -ErrorAction SilentlyContinue
Remove-GPRegistryValue -Guid $guid -Key "$base" -ValueName 'GPOName' -ErrorAction SilentlyContinue
Write-Output "Removed logon script GPO entries"
# Block Microsoft Store for caregivers
Set-GPRegistryValue -Guid $guid -Key 'HKCU\Software\Policies\Microsoft\WindowsStore' -ValueName 'RemoveWindowsStore' -Type DWord -Value 1 | Out-Null
Write-Output "Microsoft Store blocked"

View File

@@ -0,0 +1,17 @@
Import-Module ActiveDirectory
$kioskGuid = '32d76052-4d92-446c-95fb-614653f84742'
$dn = "CN={$kioskGuid},CN=Policies,CN=System,DC=cascades,DC=local"
# {C418DD9D-0D14-4efb-8FBF-CFE535C8FAC7} = Group Policy Shortcuts CSE (verified in client registry)
# {0F6B957D-509E-11D1-A7CC-0000F87571E3} = GPMC tool snap-in
$cse = '[{C418DD9D-0D14-4efb-8FBF-CFE535C8FAC7}{0F6B957D-509E-11D1-A7CC-0000F87571E3}]'
Set-ADObject $dn -Replace @{gPCUserExtensionNames=$cse}
Write-Output "CSE set: $((Get-ADObject $dn -Properties gPCUserExtensionNames).gPCUserExtensionNames)"
$gptPath = "\\cascades.local\SYSVOL\cascades.local\Policies\{$kioskGuid}\GPT.INI"
$ini = Get-Content $gptPath -Raw
$ini = $ini -replace 'gPCUserExtensionNames=.*', "gPCUserExtensionNames=$cse"
if ($ini -match 'Version=(\d+)') {
$ver = [int]$matches[1]; $newVer = ((($ver -shr 16)+1) -shl 16) -bor ($ver -band 0xFFFF)
$ini = $ini -replace "Version=\d+", "Version=$newVer"
}
Set-Content $gptPath $ini -Force
Get-Content $gptPath

View File

@@ -0,0 +1,32 @@
Import-Module ActiveDirectory
# Check what the original working GPO had
$cwDN = "CN={3B5CD9A6-A278-4676-A9FD-9396D21A8261},CN=Policies,CN=System,DC=cascades,DC=local"
$cwExt = (Get-ADObject $cwDN -Properties gPCUserExtensionNames).gPCUserExtensionNames
Write-Output "Original Caregiver Workstation CSE: $cwExt"
# Fix the kiosk GPO with the CORRECT Shortcuts CSE
$kioskGuid = '32d76052-4d92-446c-95fb-614653f84742'
$kioskDN = "CN={$kioskGuid},CN=Policies,CN=System,DC=cascades,DC=local"
# {C418DD9D-0D14-4efb-8FBF-CFE535C8FAC7} = Group Policy Shortcuts CSE
# Use same tool GUID as original, or the generic preference tool GUID
$cse = '[{C418DD9D-0D14-4efb-8FBF-CFE535C8FAC7}{CF7639F3-ABA2-41DB-97F2-81E2C5DBFC5D}]'
if ($cwExt) { $cse = $cwExt }
Set-ADObject $kioskDN -Replace @{gPCUserExtensionNames=$cse}
$verify = (Get-ADObject $kioskDN -Properties gPCUserExtensionNames).gPCUserExtensionNames
Write-Output "Kiosk GPO CSE set to: $verify"
# Update GPT.INI
$gptPath = "\\cascades.local\SYSVOL\cascades.local\Policies\{$kioskGuid}\GPT.INI"
$ini = Get-Content $gptPath -Raw
if ($ini -match 'gPCUserExtensionNames=') { $ini = $ini -replace 'gPCUserExtensionNames=.*', "gPCUserExtensionNames=$cse" } else { $ini = $ini.TrimEnd() + "`r`ngPCUserExtensionNames=$cse`r`n" }
if ($ini -match 'Version=(\d+)') {
$ver = [int]$matches[1]; $newVer = ((($ver -shr 16)+1) -shl 16) -bor ($ver -band 0xFFFF)
$ini = $ini -replace "Version=\d+", "Version=$newVer"
}
Set-Content $gptPath $ini -Force
Write-Output "GPT.INI:"
Get-Content $gptPath
# Verify Shortcuts.xml still exists
$xmlPath = "\\cascades.local\SYSVOL\cascades.local\Policies\{$kioskGuid}\User\Preferences\Shortcuts\Shortcuts.xml"
if (Test-Path $xmlPath) { Write-Output "Shortcuts.xml: EXISTS" } else { Write-Output "Shortcuts.xml: MISSING - need to restore" }

View File

@@ -0,0 +1,28 @@
Import-Module ActiveDirectory
# Kiosk GPO GUID (known)
$guid = '32d76052-4d92-446c-95fb-614653f84742'
# Correct CSE GUIDs for GP Preferences Shortcuts
# CSE: {BC75B1ED-5833-4858-9BB8-CBF0B166DF9D} = GP Preferences engine
# Tool: {0F6B957E-509E-11D1-A7CC-0000F87571E3} = Shortcuts snap-in
$cse = '[{BC75B1ED-5833-4858-9BB8-CBF0B166DF9D}{0F6B957E-509E-11D1-A7CC-0000F87571E3}]'
$dn = "CN={$guid},CN=Policies,CN=System,DC=cascades,DC=local"
Set-ADObject $dn -Replace @{gPCUserExtensionNames=$cse}
$verify = (Get-ADObject $dn -Properties gPCUserExtensionNames).gPCUserExtensionNames
Write-Output "AD gPCUserExtensionNames: $verify"
# Fix GPT.INI too
$gptPath = "\\cascades.local\SYSVOL\cascades.local\Policies\{$guid}\GPT.INI"
$ini = Get-Content $gptPath -Raw
$ini = $ini -replace 'gPCUserExtensionNames=.*', "gPCUserExtensionNames=$cse"
if ($ini -match 'Version=(\d+)') {
$ver = [int]$matches[1]; $newVer = ((($ver -shr 16)+1) -shl 16) -bor ($ver -band 0xFFFF)
$ini = $ini -replace "Version=\d+", "Version=$newVer"
}
Set-Content $gptPath $ini -Force
Write-Output "GPT.INI:"
Get-Content $gptPath
# Verify the Shortcuts.xml exists
$xmlPath = "\\cascades.local\SYSVOL\cascades.local\Policies\{$guid}\User\Preferences\Shortcuts\Shortcuts.xml"
Write-Output ""
if (Test-Path $xmlPath) { Write-Output "Shortcuts.xml: EXISTS"; Get-Content $xmlPath -Raw } else { Write-Output "Shortcuts.xml: MISSING" }

View File

@@ -0,0 +1,15 @@
# Remove per-user duplicates (Public Desktop is the canonical source)
$userDesktop = "C:\Users\pilot.test\Desktop"
Remove-Item "$userDesktop\ALIS.url" -Force -ErrorAction SilentlyContinue
Remove-Item "$userDesktop\Helpany.url" -Force -ErrorAction SilentlyContinue
Remove-Item "$userDesktop\LinkRx.url" -Force -ErrorAction SilentlyContinue
Remove-Item "$userDesktop\PharmCare.url" -Force -ErrorAction SilentlyContinue
Write-Output "Cleared per-user shortcut duplicates"
# Verify Public Desktop has the right 3
Write-Output ""
Write-Output "=== Public Desktop (all users) ==="
Get-ChildItem "C:\Users\Public\Desktop\*" -ErrorAction SilentlyContinue | ForEach-Object { Write-Output " $($_.Name)" }
Write-Output ""
Write-Output "=== pilot.test Desktop (should be empty of our URLs now) ==="
Get-ChildItem "$userDesktop\*.url","$userDesktop\*.lnk" -ErrorAction SilentlyContinue | ForEach-Object { Write-Output " $($_.Name)" }

View File

@@ -0,0 +1,12 @@
Import-Module GroupPolicy
$gpo = 'CSC - Nurse Station Kiosk'
# Auto-create and sign into Edge profile from the OS account (PRT, no prompt)
Set-GPRegistryValue -Name $gpo -Key 'HKCU\Software\Policies\Microsoft\Edge' -ValueName 'EdgeDefaultProfileEnabled' -Type DWord -Value 1 | Out-Null
# Don't show the sign-in prompt on new tab page
Set-GPRegistryValue -Name $gpo -Key 'HKCU\Software\Policies\Microsoft\Edge' -ValueName 'SignInCtaOnNtpEnabled' -Type DWord -Value 0 | Out-Null
# Disable profile picker at launch
Set-GPRegistryValue -Name $gpo -Key 'HKCU\Software\Policies\Microsoft\Edge' -ValueName 'BrowserGuestModeEnabled' -Type DWord -Value 0 | Out-Null
Set-GPRegistryValue -Name $gpo -Key 'HKCU\Software\Policies\Microsoft\Edge' -ValueName 'BrowserAddProfileEnabled' -Type DWord -Value 0 | Out-Null
Set-GPRegistryValue -Name $gpo -Key 'HKCU\Software\Policies\Microsoft\Edge' -ValueName 'UserDataSnapshotRetentionLimit' -Type DWord -Value 0 | Out-Null
Write-Output 'Updated GPO:'
Get-GPRegistryValue -Name $gpo -Key 'HKCU\Software\Policies\Microsoft\Edge' | ForEach-Object { Write-Output " $($_.ValueName)=$($_.Value)" }

View File

@@ -0,0 +1,9 @@
Import-Module GroupPolicy
$gpo = 'CSC - Nurse Station Kiosk'
# BrowserSignin=2 forces Edge to sign in with the OS account (PRT -> SSO)
# Keep SyncDisabled=1 + ClearBrowsingDataOnExit=1 so no data persists
Set-GPRegistryValue -Name $gpo -Key 'HKCU\Software\Policies\Microsoft\Edge' -ValueName 'BrowserSignin' -Type DWord -Value 2 | Out-Null
# Also enable SSO for work sites via the OS primary account
Set-GPRegistryValue -Name $gpo -Key 'HKCU\Software\Policies\Microsoft\Edge' -ValueName 'RoamingProfileSupportEnabled' -Type DWord -Value 0 | Out-Null
Write-Output 'Updated: BrowserSignin=2 (force OS account), RoamingProfileSupportEnabled=0'
Get-GPRegistryValue -Name $gpo -Key 'HKCU\Software\Policies\Microsoft\Edge' | ForEach-Object { Write-Output "$($_.ValueName)=$($_.Value)" }

View File

@@ -0,0 +1,22 @@
Import-Module GroupPolicy
Import-Module ActiveDirectory
$guid = '3B5CD9A6-A278-4676-A9FD-9396D21A8261'
# GP Preferences CSE GUIDs for Shortcuts
$cse = '[{42B5FAAE-6536-11D2-AE5A-0000F87571E3}{0F6B957D-509E-11D1-A7CC-0000F87571E3}]'
# Update AD object
$dn = "CN={$guid},CN=Policies,CN=System,DC=cascades,DC=local"
Set-ADObject $dn -Replace @{gPCUserExtensionNames=$cse}
Write-Output "AD gPCUserExtensionNames set: $cse"
# Update GPT.INI
$gptPath = "\\cascades.local\SYSVOL\cascades.local\Policies\{$guid}\GPT.INI"
$ini = Get-Content $gptPath -Raw
if ($ini -match 'Version=(\d+)') {
$ver = [int]$matches[1]; $newVer = ((($ver -shr 16)+1) -shl 16) -bor ($ver -band 0xFFFF)
$newIni = "[General]`r`nVersion=$newVer`r`ndisplayName=New Group Policy Object`r`ngPCUserExtensionNames=$cse`r`n"
Set-Content $gptPath $newIni -Force
Write-Output "GPT.INI updated, version $ver -> $newVer"
}
# Verify
$obj = Get-ADObject $dn -Properties gPCUserExtensionNames
Write-Output "Verify AD: $($obj.gPCUserExtensionNames)"
Write-Output (Get-Content $gptPath -Raw)

View File

@@ -0,0 +1,14 @@
Import-Module ActiveDirectory
# 1. Remove the duplicate created today
Remove-ADUser -Identity 'test.caregiver' -Confirm:$false
Write-Output 'Removed duplicate test.caregiver'
# 2. Ensure pilot.test is in SG-Caregivers (kiosk GPO filter) - keep SG-Caregivers-Test
Add-ADGroupMember -Identity 'SG-Caregivers' -Members 'pilot.test'
# 3. Reset password to the documented pilot value so it is deterministic
$pw = ConvertTo-SecureString 'CareTest2026!' -AsPlainText -Force
Set-ADAccountPassword -Identity 'pilot.test' -NewPassword $pw -Reset
Set-ADUser 'pilot.test' -ChangePasswordAtLogon $false -Enabled $true
$v = Get-ADUser 'pilot.test' -Properties MemberOf, Enabled
Write-Output "pilot.test enabled=$($v.Enabled)"
Write-Output "Groups: $($v.MemberOf -join '; ')"
try { Import-Module ADSync -ErrorAction Stop; Start-ADSyncSyncCycle -PolicyType Delta | Out-Null; Write-Output 'Delta sync started' } catch { Write-Output "Delta sync skipped: $_" }

View File

@@ -0,0 +1,16 @@
# Fix GPP shortcuts to use %DesktopDir% (per-user, deployed at logon by GPO)
$kioskGuid = (Get-GPO -Name 'CSC - Nurse Station Kiosk').Id
$xmlPath = "\\cascades.local\SYSVOL\cascades.local\Policies\{$kioskGuid}\User\Preferences\Shortcuts\Shortcuts.xml"
$xml = Get-Content $xmlPath -Raw
$xml = $xml -replace '%CommonDesktopDir%', '%DesktopDir%'
Set-Content $xmlPath $xml -Encoding UTF8 -Force
Write-Output "Changed shortcuts to %DesktopDir%"
# Bump version
$gptPath = "\\cascades.local\SYSVOL\cascades.local\Policies\{$kioskGuid}\GPT.INI"
$ini = Get-Content $gptPath -Raw
if ($ini -match 'Version=(\d+)') {
$ver = [int]$matches[1]; $newVer = ((($ver -shr 16)+1) -shl 16) -bor ($ver -band 0xFFFF)
$ini = $ini -replace "Version=\d+", "Version=$newVer"
Set-Content $gptPath $ini -Force
Write-Output "Version: $ver -> $newVer"
}

View File

@@ -0,0 +1,22 @@
# 1. Show all shortcuts on public + pilot.test desktop
Write-Output "=== Public Desktop ==="
Get-ChildItem "C:\Users\Public\Desktop\*.url","C:\Users\Public\Desktop\*.lnk" -ErrorAction SilentlyContinue | ForEach-Object { Write-Output " $($_.Name)" }
Write-Output "=== pilot.test Desktop ==="
Get-ChildItem "C:\Users\pilot.test\Desktop\*.url","C:\Users\pilot.test\Desktop\*.lnk" -ErrorAction SilentlyContinue | ForEach-Object { Write-Output " $($_.Name)" }
# 2. Check if M365 Apps / Office is installed
Write-Output ""
Write-Output "=== Installed Office ==="
$office = Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*","HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName -match 'Microsoft 365|Microsoft Office|Teams' } | Select-Object DisplayName, DisplayVersion
if ($office) { $office | ForEach-Object { Write-Output " $($_.DisplayName) v$($_.DisplayVersion)" } } else { Write-Output " None found" }
# 3. Check for Teams specifically
Write-Output ""
Write-Output "=== Teams ==="
$teamsNew = Get-AppxPackage -AllUsers -Name '*MSTeams*' -ErrorAction SilentlyContinue
$teamsClassic = Get-Process Teams -ErrorAction SilentlyContinue
if ($teamsNew) { Write-Output " New Teams (MSIX): $($teamsNew.Version)" } else { Write-Output " New Teams: not installed" }
$teamsExe = Test-Path "C:\Program Files\WindowsApps\MSTeams_*"
$teamsExe2 = Test-Path "C:\Program Files (x86)\Teams Installer\Teams.exe"
Write-Output " WindowsApps MSTeams: $teamsExe"
Write-Output " Classic installer: $teamsExe2"

View File

@@ -0,0 +1,6 @@
Import-Module GroupPolicy
$gpo = 'CSC - Caregiver Device Lockdown'
# Hide last logged-on username on the lock/login screen
Set-GPRegistryValue -Name $gpo -Key 'HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System' -ValueName 'DontDisplayLastUserName' -Type DWord -Value 1 | Out-Null
Set-GPRegistryValue -Name $gpo -Key 'HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System' -ValueName 'dontdisplaylockeduser' -Type DWord -Value 3 | Out-Null
Write-Output "Added DontDisplayLastUserName=1, dontdisplaylockeduser=3"

View File

@@ -0,0 +1,50 @@
Import-Module GroupPolicy
# Identify which GPO this is
$gpo = Get-GPO -Guid '3B5CD9A6-A278-4676-A9FD-9396D21A8261'
Write-Output "GPO: $($gpo.DisplayName) (ID: $($gpo.Id))"
Write-Output "Status: $($gpo.GpoStatus)"
# Remove the GPP Shortcuts.xml (stops it recreating shortcuts on login)
$path = "\\cascades.local\SYSVOL\cascades.local\Policies\{3B5CD9A6-A278-4676-A9FD-9396D21A8261}\User\Preferences\Shortcuts\Shortcuts.xml"
if (Test-Path $path) {
Remove-Item $path -Force
Write-Output "REMOVED: $path"
# Clean up empty dir
$dir = Split-Path $path
if ((Get-ChildItem $dir -ErrorAction SilentlyContinue).Count -eq 0) {
Remove-Item $dir -Force
Write-Output "Cleaned empty Shortcuts dir"
}
} else {
Write-Output "Already removed"
}
# Bump GPO version so clients pick up the change
# Read current version, increment user version
$gpoPath = "\\cascades.local\SYSVOL\cascades.local\Policies\{3B5CD9A6-A278-4676-A9FD-9396D21A8261}\GPT.INI"
$ini = Get-Content $gpoPath -Raw
Write-Output ""
Write-Output "GPT.INI before:"
Write-Output $ini
# Parse version: low 16 bits = computer, high 16 bits = user
if ($ini -match 'Version=(\d+)') {
$ver = [int]$matches[1]
$userVer = ($ver -shr 16) + 1
$compVer = $ver -band 0xFFFF
$newVer = ($userVer -shl 16) -bor $compVer
$ini = $ini -replace "Version=\d+", "Version=$newVer"
Set-Content $gpoPath $ini -Force
Write-Output "GPT.INI after (version $ver -> $newVer):"
Write-Output $ini
}
# Also clean the per-user desktop shortcuts one more time
Get-ChildItem "C:\Users" -Directory | Where-Object { $_.Name -notin 'Public','Default','Default User','All Users' } | ForEach-Object {
$desk = Join-Path $_.FullName "Desktop"
foreach ($f in 'ALIS.url','Helpany.url','PharmCare.url','LinkRx.url') {
$p = Join-Path $desk $f
if (Test-Path $p) { Remove-Item $p -Force }
}
}
Write-Output ""
Write-Output "Cleaned per-user desktop shortcuts"

View File

@@ -0,0 +1,6 @@
Import-Module GroupPolicy
$gpo = 'CSC - Nurse Station Kiosk'
Set-GPRegistryValue -Name $gpo -Key 'HKCU\Software\Policies\Microsoft\Edge' -ValueName 'HideFirstRunExperience' -Type DWord -Value 1 | Out-Null
Set-GPRegistryValue -Name $gpo -Key 'HKCU\Software\Policies\Microsoft\Edge' -ValueName 'AutoImportAtFirstRun' -Type DWord -Value 4 | Out-Null
Write-Output 'Added: HideFirstRunExperience=1, AutoImportAtFirstRun=4 (disabled)'
Get-GPRegistryValue -Name $gpo -Key 'HKCU\Software\Policies\Microsoft\Edge' | ForEach-Object { Write-Output "$($_.ValueName)=$($_.Value)" }

View File

@@ -0,0 +1,4 @@
# List all packaged apps installed for all users on this machine
Get-AppxPackage -AllUsers | Select-Object Name, PackageFamilyName | Sort-Object Name | ForEach-Object {
Write-Output "$($_.Name) | $($_.PackageFamilyName)"
}

View File

@@ -0,0 +1,36 @@
Import-Module GroupPolicy
# Move GPP shortcuts from CSC - Caregiver Workstation to CSC - Nurse Station Kiosk
$kioskGuid = (Get-GPO -Name 'CSC - Nurse Station Kiosk').Id
$cwGuid = '3B5CD9A6-A278-4676-A9FD-9396D21A8261'
# Read current shortcuts XML from Caregiver Workstation GPO
$srcDir = "\\cascades.local\SYSVOL\cascades.local\Policies\{$cwGuid}\User\Preferences\Shortcuts"
$srcXml = "$srcDir\Shortcuts.xml"
$content = Get-Content $srcXml -Raw -ErrorAction SilentlyContinue
Write-Output "Source XML exists: $($null -ne $content)"
# Write to Nurse Station Kiosk GPO
$dstDir = "\\cascades.local\SYSVOL\cascades.local\Policies\{$kioskGuid}\User\Preferences\Shortcuts"
New-Item -ItemType Directory -Path $dstDir -Force | Out-Null
Set-Content "$dstDir\Shortcuts.xml" $content -Encoding UTF8 -Force
Write-Output "Copied shortcuts to kiosk GPO"
# Remove from Caregiver Workstation GPO
Remove-Item $srcXml -Force
Write-Output "Removed from Caregiver Workstation GPO"
# Set CSE GUIDs on kiosk GPO AD object
$cse = '[{42B5FAAE-6536-11D2-AE5A-0000F87571E3}{0F6B957D-509E-11D1-A7CC-0000F87571E3}]'
$dn = "CN={$kioskGuid},CN=Policies,CN=System,DC=cascades,DC=local"
$existing = (Get-ADObject $dn -Properties gPCUserExtensionNames).gPCUserExtensionNames
if ($existing) { $merged = $existing + $cse } else { $merged = $cse }
Set-ADObject $dn -Replace @{gPCUserExtensionNames=$merged}
Write-Output "CSE GUIDs set on kiosk GPO"
# Bump kiosk GPO version
$gptPath = "\\cascades.local\SYSVOL\cascades.local\Policies\{$kioskGuid}\GPT.INI"
$ini = Get-Content $gptPath -Raw
if ($ini -match 'Version=(\d+)') {
$ver = [int]$matches[1]; $newVer = ((($ver -shr 16)+1) -shl 16) -bor ($ver -band 0xFFFF)
$ini = $ini -replace "Version=\d+", "Version=$newVer"
# Add CSE to GPT.INI too
if ($ini -notmatch 'gPCUserExtensionNames') { $ini = $ini.TrimEnd() + "`r`ngPCUserExtensionNames=$cse`r`n" }
Set-Content $gptPath $ini -Force
Write-Output "Kiosk GPO version bumped: $ver -> $newVer"
}
Write-Output (Get-Content $gptPath -Raw)

View File

@@ -0,0 +1,49 @@
# Remove user-facing apps caregivers don't need
# Store is blocked so they can't reinstall
$remove = @(
'4DF9E0F8.Netflix',
'7EE7776C.LinkedInforWindows',
'AcerIncorporated.AcerCareCenterS',
'AcerIncorporated.AcerCollectionS',
'AcerIncorporated.AcerRegistration',
'C27EB4BA.DropboxOEM',
'Evernote.Evernote',
'Microsoft.549981C3F5F10',
'Microsoft.Copilot',
'Microsoft.Edge.GameAssist',
'Microsoft.GamingApp',
'Microsoft.Getstarted',
'Microsoft.Microsoft3DViewer',
'Microsoft.Messaging',
'Microsoft.MixedReality.Portal',
'Microsoft.OneConnect',
'Microsoft.People',
'Microsoft.Print3D',
'Microsoft.SkypeApp',
'Microsoft.WindowsCamera',
'Microsoft.WindowsMaps',
'Microsoft.Xbox.TCUI',
'Microsoft.XboxApp',
'Microsoft.XboxGameOverlay',
'Microsoft.XboxGamingOverlay',
'Microsoft.XboxIdentityProvider',
'Microsoft.XboxSpeechToTextOverlay',
'Microsoft.YourPhone',
'Microsoft.ZuneVideo',
'SpotifyAB.SpotifyMusic',
'Microsoft.WindowsTerminal'
)
foreach ($app in $remove) {
$pkg = Get-AppxPackage -AllUsers -Name $app -ErrorAction SilentlyContinue
if ($pkg) {
$pkg | Remove-AppxPackage -AllUsers -ErrorAction SilentlyContinue
Write-Output "Removed: $app"
}
# Also remove provisioned (prevents reinstall on new profiles)
$prov = Get-AppxProvisionedPackage -Online -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName -eq $app }
if ($prov) {
$prov | Remove-AppxProvisionedPackage -Online -ErrorAction SilentlyContinue
Write-Output "Deprovisioned: $app"
}
}
Write-Output "Done. Kept: Edge, Office, Teams, Outlook, Calculator, Notepad, printing."

View File

@@ -0,0 +1,15 @@
$dir = "\\cascades.local\SYSVOL\cascades.local\Policies\{3B5CD9A6-A278-4676-A9FD-9396D21A8261}\User\Preferences\Shortcuts"
New-Item -ItemType Directory -Path $dir -Force | Out-Null
$a = '<Shortcut clsid="{4F2F7C55-2790-433e-8127-0739D1CFA327}" name="ALIS" status="ALIS" image="0" changed="2026-07-17 19:00:00" uid="{0889D408-08BF-4321-BA2A-486053F0533B}" bypassErrors="1"><Properties shortcutPath="%CommonDesktopDir%\ALIS" pidl="" targetType="URL" action="R" comment="" startIn="" arguments="" iconIndex="0" targetPath="https://cascadestucson.alisonline.com/" iconPath="" window="" shortcutKey="0"/></Shortcut>'
$b = '<Shortcut clsid="{4F2F7C55-2790-433e-8127-0739D1CFA327}" name="PharmCare" status="PharmCare" image="0" changed="2026-07-17 19:00:00" uid="{7B9E504F-AA3A-4E44-B3D5-E7E952FA556F}" bypassErrors="1"><Properties shortcutPath="%CommonDesktopDir%\PharmCare" pidl="" targetType="URL" action="R" comment="" startIn="" arguments="" iconIndex="0" targetPath="https://pharmcare.linkrxnow.com/" iconPath="" window="" shortcutKey="0"/></Shortcut>'
$c = '<Shortcut clsid="{4F2F7C55-2790-433e-8127-0739D1CFA327}" name="Helpany" status="Helpany" image="0" changed="2026-07-17 19:00:00" uid="{38EE1CA4-25AE-4E02-8CA5-DECF837BDDBD}" bypassErrors="1"><Properties shortcutPath="%CommonDesktopDir%\Helpany" pidl="" targetType="URL" action="R" comment="" startIn="" arguments="" iconIndex="0" targetPath="https://app.helpany.com/start" iconPath="" window="" shortcutKey="0"/></Shortcut>'
$xml = '<?xml version="1.0" encoding="utf-8"?><Shortcuts clsid="{872C5C8A-6BBD-4d24-B962-D7A6F92B6F1A}">' + $a + $b + $c + '</Shortcuts>'
Set-Content "$dir\Shortcuts.xml" $xml -Encoding UTF8 -Force
Write-Output "Restored GPP shortcuts -> CommonDesktopDir"
$gpoPath = "\\cascades.local\SYSVOL\cascades.local\Policies\{3B5CD9A6-A278-4676-A9FD-9396D21A8261}\GPT.INI"
$ini = Get-Content $gpoPath -Raw
if ($ini -match 'Version=(\d+)') {
$ver = [int]$matches[1]; $newVer = ((($ver -shr 16)+1) -shl 16) -bor ($ver -band 0xFFFF)
Set-Content $gpoPath ($ini -replace "Version=\d+","Version=$newVer") -Force
Write-Output "GPO version: $ver -> $newVer"
}

View File

@@ -0,0 +1,13 @@
$guid = '32d76052-4d92-446c-95fb-614653f84742'
# Write logon script
$bat = "@echo off`r`nif not exist `"%USERPROFILE%\Desktop\ALIS.url`" (`r`n echo [InternetShortcut]> `"%USERPROFILE%\Desktop\ALIS.url`"`r`n echo URL=https://cascadestucson.alisonline.com/>> `"%USERPROFILE%\Desktop\ALIS.url`"`r`n)`r`nif not exist `"%USERPROFILE%\Desktop\PharmCare.url`" (`r`n echo [InternetShortcut]> `"%USERPROFILE%\Desktop\PharmCare.url`"`r`n echo URL=https://pharmcare.linkrxnow.com/>> `"%USERPROFILE%\Desktop\PharmCare.url`"`r`n)`r`nif not exist `"%USERPROFILE%\Desktop\Helpany.url`" (`r`n echo [InternetShortcut]> `"%USERPROFILE%\Desktop\Helpany.url`"`r`n echo URL=https://app.helpany.com/start>> `"%USERPROFILE%\Desktop\Helpany.url`"`r`n)"
$gpoScripts = "\\cascades.local\SYSVOL\cascades.local\Policies\{$guid}\User\Scripts\Logon"
New-Item -ItemType Directory -Path $gpoScripts -Force | Out-Null
Set-Content "$gpoScripts\deploy-caregiver-shortcuts.bat" $bat -Force
$ini = "[Logon]`r`n0CmdLine=deploy-caregiver-shortcuts.bat`r`n0Parameters=`r`n"
Set-Content "$gpoScripts\scripts.ini" $ini -Force
# Remove broken GPP
$xmlDir = "\\cascades.local\SYSVOL\cascades.local\Policies\{$guid}\User\Preferences"
if (Test-Path $xmlDir) { Remove-Item $xmlDir -Recurse -Force }
Write-Output "Logon script + scripts.ini written, GPP removed"
Get-Content "$gpoScripts\deploy-caregiver-shortcuts.bat"

View File

@@ -0,0 +1,16 @@
Import-Module ActiveDirectory
$guid = '32d76052-4d92-446c-95fb-614653f84742'
$dn = "CN={$guid},CN=Policies,CN=System,DC=cascades,DC=local"
$cse = '[{42B5FAAE-6536-11D2-AE5A-0000F87571E3}{40B6664F-4972-11D1-A7CA-0000F87571E3}]'
Set-ADObject $dn -Replace @{gPCUserExtensionNames=$cse}
Write-Output "CSE: $((Get-ADObject $dn -Properties gPCUserExtensionNames).gPCUserExtensionNames)"
$gptPath = "\\cascades.local\SYSVOL\cascades.local\Policies\{$guid}\GPT.INI"
$ini = Get-Content $gptPath -Raw
if ($ini -match 'gPCUserExtensionNames=') { $ini = $ini -replace 'gPCUserExtensionNames=.*', "gPCUserExtensionNames=$cse" } else { $ini = $ini.TrimEnd() + "`r`ngPCUserExtensionNames=$cse`r`n" }
if ($ini -match 'Version=(\d+)') {
$ver = [int]$matches[1]; $newVer = ((($ver -shr 16)+1) -shl 16) -bor ($ver -band 0xFFFF)
$ini = $ini -replace "Version=\d+", "Version=$newVer"
}
Set-Content $gptPath $ini -Force
Write-Output "GPT.INI:"
Get-Content $gptPath

View File

@@ -0,0 +1,70 @@
Import-Module GroupPolicy
$guid = '32d76052-4d92-446c-95fb-614653f84742'
# 1. Write the logon script to SYSVOL (netlogon share)
$scriptContent = @'
@echo off
REM Deploy caregiver desktop shortcuts
if not exist "%USERPROFILE%\Desktop\ALIS.url" (
echo [InternetShortcut] > "%USERPROFILE%\Desktop\ALIS.url"
echo URL=https://cascadestucson.alisonline.com/ >> "%USERPROFILE%\Desktop\ALIS.url"
)
if not exist "%USERPROFILE%\Desktop\PharmCare.url" (
echo [InternetShortcut] > "%USERPROFILE%\Desktop\PharmCare.url"
echo URL=https://pharmcare.linkrxnow.com/ >> "%USERPROFILE%\Desktop\PharmCare.url"
)
if not exist "%USERPROFILE%\Desktop\Helpany.url" (
echo [InternetShortcut] > "%USERPROFILE%\Desktop\Helpany.url"
echo URL=https://app.helpany.com/start >> "%USERPROFILE%\Desktop\Helpany.url"
)
'@
$netlogon = "\\cascades.local\SYSVOL\cascades.local\scripts"
Set-Content "$netlogon\deploy-caregiver-shortcuts.bat" $scriptContent -Force
Write-Output "Logon script written to: $netlogon\deploy-caregiver-shortcuts.bat"
# 2. Remove the broken GPP Shortcuts.xml
$xmlDir = "\\cascades.local\SYSVOL\cascades.local\Policies\{$guid}\User\Preferences\Shortcuts"
if (Test-Path $xmlDir) {
Remove-Item $xmlDir -Recurse -Force
Write-Output "Removed GPP Shortcuts dir"
}
# 3. Set the logon script on the kiosk GPO
Set-GPRegistryValue -Guid $guid -Key 'HKCU\Software\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Logon\0\0' -ValueName 'Script' -Type String -Value 'deploy-caregiver-shortcuts.bat' | Out-Null
Set-GPRegistryValue -Guid $guid -Key 'HKCU\Software\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Logon\0\0' -ValueName 'Parameters' -Type String -Value '' | Out-Null
Set-GPRegistryValue -Guid $guid -Key 'HKCU\Software\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Logon\0\0' -ValueName 'IsPowershell' -Type DWord -Value 0 | Out-Null
Set-GPRegistryValue -Guid $guid -Key 'HKCU\Software\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Logon\0' -ValueName 'GPO-ID' -Type String -Value "cn={$guid},cn=policies,cn=system,DC=cascades,DC=local" | Out-Null
Set-GPRegistryValue -Guid $guid -Key 'HKCU\Software\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Logon\0' -ValueName 'SOM-ID' -Type String -Value 'OU=Caregiver Devices,OU=Staff PCs,OU=Workstations,DC=cascades,DC=local' | Out-Null
Set-GPRegistryValue -Guid $guid -Key 'HKCU\Software\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Logon\0' -ValueName 'FileSysPath' -Type String -Value "\\cascades.local\SysVol\cascades.local\Policies\{$guid}\User\Scripts\Logon" | Out-Null
Set-GPRegistryValue -Guid $guid -Key 'HKCU\Software\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Logon\0' -ValueName 'DisplayName' -Type String -Value 'CSC - Nurse Station Kiosk' | Out-Null
Set-GPRegistryValue -Guid $guid -Key 'HKCU\Software\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Logon\0' -ValueName 'GPOName' -Type String -Value $guid | Out-Null
Write-Output "Logon script GPO registry entries set"
# 4. Also copy the bat into the GPO's own scripts folder
$gpoScripts = "\\cascades.local\SYSVOL\cascades.local\Policies\{$guid}\User\Scripts\Logon"
New-Item -ItemType Directory -Path $gpoScripts -Force | Out-Null
Copy-Item "$netlogon\deploy-caregiver-shortcuts.bat" "$gpoScripts\deploy-caregiver-shortcuts.bat" -Force
Write-Output "Script copied to GPO scripts folder"
# 5. Write scripts.ini
$ini = "[Logon]`r`n0CmdLine=deploy-caregiver-shortcuts.bat`r`n0Parameters=`r`n"
Set-Content "$gpoScripts\scripts.ini" $ini -Force
Write-Output "scripts.ini written"
# 6. Update CSE GUIDs for Scripts
$scriptsCSE = '[{42B5FAAE-6536-11D2-AE5A-0000F87571E3}{40B6664F-4972-11D1-A7CA-0000F87571E3}]'
$dn = "CN={$guid},CN=Policies,CN=System,DC=cascades,DC=local"
Set-ADObject $dn -Replace @{gPCUserExtensionNames=$scriptsCSE}
Write-Output "CSE GUIDs set for Scripts"
# 7. Bump version
$gptPath = "\\cascades.local\SYSVOL\cascades.local\Policies\{$guid}\GPT.INI"
$gptIni = Get-Content $gptPath -Raw
$gptIni = $gptIni -replace 'gPCUserExtensionNames=.*', "gPCUserExtensionNames=$scriptsCSE"
if ($gptIni -match 'Version=(\d+)') {
$ver = [int]$matches[1]; $newVer = ((($ver -shr 16)+1) -shl 16) -bor ($ver -band 0xFFFF)
$gptIni = $gptIni -replace "Version=\d+", "Version=$newVer"
}
Set-Content $gptPath $gptIni -Force
Write-Output "GPT.INI updated"
Get-Content $gptPath

View File

@@ -0,0 +1,19 @@
Import-Module GroupPolicy
Write-Output "=== Kiosk GPO permissions ==="
Get-GPPermission -Name 'CSC - Nurse Station Kiosk' -All | ForEach-Object { Write-Output " $($_.Trustee.Name) ($($_.Trustee.SidType)): $($_.Permission) denied=$($_.Denied)" }
Write-Output ""
Write-Output "=== Kiosk GPO links ==="
$gpo = Get-GPO -Name 'CSC - Nurse Station Kiosk'
Write-Output " ID: $($gpo.Id) Status: $($gpo.GpoStatus)"
# Check links via AD
$links = Get-ADOrganizationalUnit -Filter * -Properties gpLink | Where-Object { $_.gpLink -match $gpo.Id }
$links | ForEach-Object { Write-Output " Linked: $($_.DistinguishedName)" }
Write-Output ""
Write-Output "=== Caregiver Workstation GPO permissions ==="
Get-GPPermission -Name 'CSC - Caregiver Workstation' -All | ForEach-Object { Write-Output " $($_.Trustee.Name) ($($_.Trustee.SidType)): $($_.Permission) denied=$($_.Denied)" }
Write-Output ""
Write-Output "=== Caregiver Workstation GPO links ==="
$gpo2 = Get-GPO -Name 'CSC - Caregiver Workstation'
Write-Output " ID: $($gpo2.Id) Status: $($gpo2.GpoStatus)"
$links2 = Get-ADOrganizationalUnit -Filter * -Properties gpLink | Where-Object { $_.gpLink -match $gpo2.Id }
$links2 | ForEach-Object { Write-Output " Linked: $($_.DistinguishedName)" }

View File

@@ -0,0 +1,40 @@
Write-Output "=== 1. OU placement ==="
$comp = ([adsisearcher]"(&(objectClass=computer)(cn=NURSESTATION-PC))").FindOne()
Write-Output "DN: $($comp.Properties.distinguishedname)"
Write-Output ""
Write-Output "=== 2. GPOs linked to this machine ==="
gpresult /scope computer /r 2>&1 | Select-String "Applied Group Policy|CSC|Caregiver|Kiosk|Nurse|Lockdown"
Write-Output ""
Write-Output "=== 3. Loopback processing (UserPolicyMode) ==="
$lp = Get-ItemProperty "HKLM:\Software\Policies\Microsoft\Windows\System" -Name UserPolicyMode -ErrorAction SilentlyContinue
if ($lp) { Write-Output "UserPolicyMode=$($lp.UserPolicyMode) (1=Merge)" } else { Write-Output "NOT SET" }
Write-Output ""
Write-Output "=== 4. DontDisplayLastUserName ==="
$dl = Get-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\Policies\System" -Name DontDisplayLastUserName -ErrorAction SilentlyContinue
Write-Output "DontDisplayLastUserName=$($dl.DontDisplayLastUserName)"
Write-Output ""
Write-Output "=== 5. Kiosk GPO security filter (who gets locked down) ==="
Import-Module GroupPolicy
$acl = (Get-GPO -Name 'CSC - Nurse Station Kiosk').Path
$perms = Get-GPPermission -Name 'CSC - Nurse Station Kiosk' -All
$perms | ForEach-Object { Write-Output " $($_.Trustee.Name) : $($_.Permission)" }
Write-Output ""
Write-Output "=== 6. Scheduled task: profile cleanup ==="
Get-ScheduledTask -TaskName '*Caregiver*' -ErrorAction SilentlyContinue | ForEach-Object {
Write-Output "Task: $($_.TaskName) State: $($_.State)"
Write-Output "Trigger: $($_.Triggers | ForEach-Object { $_.CimClass.CimClassName })"
}
Write-Output ""
Write-Output "=== 7. Desktop shortcuts ==="
Write-Output "Public:"
Get-ChildItem "C:\Users\Public\Desktop\*.url","C:\Users\Public\Desktop\*.lnk" -ErrorAction SilentlyContinue | ForEach-Object { Write-Output " $($_.Name)" }
Write-Output ""
Write-Output "=== 8. Hybrid join + PRT capable ==="
dsregcmd /status | Select-String "AzureAdJoined|DomainJoined|TenantId" | ForEach-Object { $_.Line.Trim() }

View File

@@ -0,0 +1,100 @@
# Cascades of Tucson — Nurse Station Kiosk GPO Build (NURSESTATION-PC)
## User
- **User:** Howard Enos (howard)
- **Machine:** Howard-Home
- **Role:** tech
## Session Summary
Continued from the earlier 7/17 session (roadmap refresh + Juan Andrade offboard). This session built and iteratively debugged the nurse-station kiosk configuration for NURSESTATION-PC, delivering on WS3 step 3b: shared caregiver desktops with phone-parity lockdown.
The kiosk GPO (`CSC - Nurse Station Kiosk`, GUID `32d76052-4d92-446c-95fb-614653f84742`) was built with Edge policies for caregivers: `BrowserSignin=2` (force OS account sign-in for SSO), `EdgeDefaultProfileEnabled=1` (auto-profile from PRT, no picker), `ClearBrowsingDataOnExit=1`, `PasswordManagerEnabled=0`, `AutofillAddressEnabled=0`, `AutofillCreditCardEnabled=0`, `SyncDisabled=1`, `HideFirstRunExperience=1`, `AutoImportAtFirstRun=4`, `BrowserGuestModeEnabled=0`, `BrowserAddProfileEnabled=0`, `SignInCtaOnNtpEnabled=0`, `RoamingProfileSupportEnabled=0`, `UserDataSnapshotRetentionLimit=0`. The GPO is linked to `OU=Caregiver Devices,OU=Staff PCs,OU=Workstations` with `GpoApply` filtered to `SG-Caregivers` only; non-caregivers log in with no lockdown via the loopback merge (`UserPolicyMode=1`) on the `CSC - Caregiver Device Lockdown` GPO.
GPP Shortcuts (ALIS, PharmCare, Helpany) were deployed via the kiosk GPO after multiple rounds of debugging. The root cause of non-delivery was wrong CSE GUIDs: the correct CSE for GP Preferences Shortcuts is `{C418DD9D-0D14-4efb-8FBF-CFE535C8FAC7}` (verified from client registry), not `{BC75B1ED-...}` (Printers) or `{42B5FAAE-...}` (Scripts). Shortcuts target `%DesktopDir%` (per-user desktop), deployed at logon via loopback. The original `CSC - Caregiver Workstation` GPO shortcuts (in the user OU, filtered to `SG-Caregivers-Test`) were moved to the kiosk GPO and removed from the original to prevent duplication.
Additional configurations: `DontDisplayLastUserName=1` + `dontdisplaylockeduser=3` on the lockdown GPO (hides previous usernames on the login screen); both nurse printers (`\\CS-SERVER\Nurses - Brother MFC-L8900CDW` and `\\CS-SERVER\Health Services - Konica Minolta C368`) added as machine-level connections via `rundll32 printui.dll /ga`; UI restrictions (NoRun, NoControlPanel, NoSetFolders, DisableCMD, DisableRegistryTools, DisableTaskMgr, DisableUserInstalls, NoNetHood, NoRecentDocsHistory, ClearRecentDocsOnExit) applied via the kiosk GPO; Microsoft Store blocked via `RemoveWindowsStore=1`.
Session ended with app restriction still incomplete. The UI restrictions (no CMD/PowerShell/Settings/Control Panel/Run/Task Manager/Store) are in place, but user-facing Store apps (Camera, Netflix, Xbox, Spotify, etc.) are still launchable from the Start menu. Howard rejected removing the apps from the machine because non-caregiver users need access. AppLocker with group-specific Deny rules for SG-Caregivers is the correct next step, but was not completed this session.
## Key Decisions
- `BrowserSignin=2` + `EdgeDefaultProfileEnabled=1` chosen to force Edge SSO via PRT, eliminating the need for caregivers to enter credentials in the browser after Windows login. `BrowserSignin=0` (original setting) was blocking PRT passthrough entirely.
- GPP shortcuts placed in the kiosk GPO (machine OU, SG-Caregivers filter) rather than the Caregiver Workstation GPO (user OU, SG-Caregivers-Test filter) so all SG-Caregivers members get shortcuts on any caregiver device, not just test-group members.
- Shortcuts use `%DesktopDir%` (per-user desktop) not `%CommonDesktopDir%` (Public Desktop) because GPP user preferences targeting CommonDesktopDir require a user logon to process but the chicken-and-egg problem means the first login has no shortcuts.
- Printers added as machine-level connections (`/ga` flag) rather than per-user connections so every user gets them automatically without GPO printer deployment complexity.
- `DontDisplayLastUserName` placed in the `CSC - Caregiver Device Lockdown` GPO (not the kiosk GPO) because it's a computer-level policy (HKLM) and must apply regardless of which user is at the login screen.
- App removal rejected by Howard (non-caregivers need the apps) — AppLocker with SG-Caregivers Deny rules is the planned approach for the next session.
- `pilot.test` AD account (from June) used as the test identity instead of creating a new `test.caregiver` account. A duplicate `test.caregiver` was created by mistake and deleted same session. `pilot.test` was added to `SG-Caregivers` (kiosk GPO filter) in addition to existing `SG-Caregivers-Test` membership. Password reset to `CareTest2026!`.
## Problems Encountered
- **PRT not issuing (`AzureAdPrt : NO`):** NURSESTATION-PC was hybrid-joined but PRT acquisition failed. Root cause: stale PRT attempt cached for `sysadmin@cascadestucson.com` with `AADSTS50126` (invalid credentials). Fixed by clearing WAM token broker cache (`Microsoft.AAD.BrokerPlugin_cw5n1h2txyewy\AC\TokenBroker`) for all users + reboot.
- **Edge showing sync/profile picker:** `BrowserSignin=0` blocked Edge from using the PRT entirely. Changed to `BrowserSignin=2` (force OS account) + `EdgeDefaultProfileEnabled=1` (auto-profile, no picker). Also needed to clear stale Edge profile data (`C:\Users\pilot.test\AppData\Local\Microsoft\Edge\User Data`).
- **Duplicate desktop shortcuts:** Three sources stacking: (1) Public Desktop (manually placed), (2) per-user desktop from Default profile (copied at first login), (3) GPP shortcuts from `CSC - Caregiver Workstation` GPO (`action="R"` to `%DesktopDir%`). Fixed by cleaning Default profile desktop, removing manual Public Desktop shortcuts, and consolidating all shortcuts into the kiosk GPO GPP only.
- **GPP shortcuts not deploying (multiple rounds):** Wrong CSE GUIDs on the GPO AD object and GPT.INI. Tried `{42B5FAAE-...}` (Scripts) and `{BC75B1ED-...}` (Printers) before discovering the correct Shortcuts CSE is `{C418DD9D-0D14-4efb-8FBF-CFE535C8FAC7}` via `HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions` on the client machine. Also discovered the original `CSC - Caregiver Workstation` GPO was filtered to `SG-Caregivers-Test` (not `SG-Caregivers`), so `a.vallejo` (in SG-Caregivers only) never received those shortcuts.
- **CMD window popup at logon:** Caused by a `.bat` logon script configured in the kiosk GPO (created as a shortcut deployment workaround before GPP was fixed). Removed the scripts.ini, Scripts directory, and GPO registry entries for the logon script.
- **Duplicate AD test account:** `test.caregiver` created, then discovered `pilot.test` already existed from June with ALIS staff email mapping and Business Premium license. Deleted `test.caregiver`, added `pilot.test` to `SG-Caregivers`, reset password.
## Configuration Changes
**On CS-SERVER (via RMM):**
- GPO `CSC - Nurse Station Kiosk` (`32d76052-4d92-446c-95fb-614653f84742`): 15 Edge HKCU policies, GPP Shortcuts.xml (ALIS/PharmCare/Helpany to `%DesktopDir%`), CSE GUIDs `[{C418DD9D-0D14-4efb-8FBF-CFE535C8FAC7}{0F6B957D-509E-11D1-A7CC-0000F87571E3}]`, UI restrictions (NoRun, NoControlPanel, DisableCMD, DisableRegistryTools, DisableTaskMgr, DisableUserInstalls, NoNetHood, NoRecentDocsHistory, ClearRecentDocsOnExit, NoSetFolders, NoSMHelp), RemoveWindowsStore=1
- GPO `CSC - Caregiver Device Lockdown`: added `DontDisplayLastUserName=1` + `dontdisplaylockeduser=3` (HKLM)
- GPO `CSC - Caregiver Workstation` (`3B5CD9A6-A278-4676-A9FD-9396D21A8261`): GPP Shortcuts.xml removed (moved to kiosk GPO)
- AD: `pilot.test` added to `SG-Caregivers`, password reset; duplicate `test.caregiver` account created then deleted
**On NURSESTATION-PC (via RMM):**
- WAM token broker cache cleared for all user profiles
- Edge profile data cleared for pilot.test
- Per-user + Default profile desktop shortcuts cleaned (Public Desktop cleared, GPO handles deployment)
- Machine-level printer connections: `\\CS-SERVER\Nurses - Brother MFC-L8900CDW` + `\\CS-SERVER\Health Services - Konica Minolta C368` via `rundll32 printui.dll /ga`
- Multiple gpupdate /force cycles
**Local scripts created:**
- `clients/cascades-tucson/scripts/`: create-test-caregiver.ps1, align-test-pilot-upn.ps1, audit-test-accounts.ps1, fix-pilot-test-accounts.ps1, kiosk-gpo-firstrun.ps1, fix-edge-sso.ps1, fix-edge-auto-profile.ps1, clear-prt-cache.ps1, check-hybrid-join.ps1, check-printers.ps1, add-nurse-printer.ps1, find-all-shortcuts.ps1, dedup-shortcuts-final.ps1, find-shortcut-source.ps1, identify-gpo-and-fix.ps1, restore-gpp-shortcuts-public.ps1, fix-shortcut-target.ps1, move-shortcuts-to-kiosk-gpo.ps1, cleanup-and-gpupdate.ps1, check-gpp-apply.ps1, debug-gpp-shortcuts.ps1, debug-gpp-2.ps1, check-cse-client.ps1, fix-cse-final.ps1, fix-cse-correct.ps1, fix-gpo-cse-guids.ps1, verify-kiosk-config.ps1, verify-kiosk-2.ps1, caregiver-app-restrictions.ps1, app-restrict-1.ps1, app-restrict-2.ps1, fix-cmd-popup.ps1, list-packaged-apps.ps1, remove-unwanted-apps.ps1, hide-last-user-gpupdate.ps1, clear-edge-profiles-gpupdate.ps1, check-avallejo.ps1
## Credentials & Secrets
- `pilot.test` AD account: `cascades\pilot.test` / `CareTest2026!` (password reset this session; vault: `clients/cascades-tucson/pilot-test-ad.sops.yaml`)
- `a.vallejo` caregiver account: `cascades\a.vallejo` / `Sunrise4827` (from vault: `clients/cascades-tucson/caregiver-temp-passwords-2026-07-01.sops.yaml`)
- Duplicate `test.caregiver` account created with password `KioskTest-7492!`, then DELETED same session. Vault entry `test-caregiver-ad.sops.yaml` also deleted.
## Infrastructure & Servers
- NURSESTATION-PC: RMM agent `f5a89784-834f-47b1-82e2-7e3e9dd337ff`, hybrid-joined (AzureAdJoined=YES, DomainJoined=YES), DeviceId `d3bf931f-f128-4261-8398-b46c34a4b342`, TenantId `207fa277-e9d8-4eb7-ada1-1064d2221498`, DN `CN=NURSESTATION-PC,OU=Caregiver Devices,OU=Staff PCs,OU=Workstations,DC=cascades,DC=local`
- CS-SERVER: RMM agent `c39f1de7-d5b6-45ae-b132-e06977ab1713`
- Kiosk GPO: `CSC - Nurse Station Kiosk`, GUID `32d76052-4d92-446c-95fb-614653f84742`, linked to `OU=Caregiver Devices`, GpoApply=SG-Caregivers
- Lockdown GPO: `CSC - Caregiver Device Lockdown`, UserPolicyMode=1 (loopback merge)
- Caregiver Workstation GPO: `CSC - Caregiver Workstation`, GUID `3B5CD9A6-A278-4676-A9FD-9396D21A8261`, linked to `OU=Caregivers,OU=Departments`, GpoApply=SG-Caregivers-Test
- Reception GPO `CSC - Reception Workstation Policy` also applies to NURSESTATION-PC (pre-existing, flagged)
- Printers: `\\CS-SERVER\Nurses - Brother MFC-L8900CDW` (TCP_192.168.2.75), `\\CS-SERVER\Health Services - Konica Minolta C368` (TCP_192.168.1.138)
- GP Preferences Shortcuts CSE GUID: `{C418DD9D-0D14-4efb-8FBF-CFE535C8FAC7}` (verified from client `HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions`)
## Commands & Outputs
- `dsregcmd /status` on NURSESTATION-PC: `AzureAdJoined: YES`, `DomainJoined: YES`, `AzureAdPrt: NO` (initially), `DeviceAuthStatus: SUCCESS`; PRT failure was `AADSTS50126` for stale `sysadmin@` credential
- `rundll32 printui.dll,PrintUIEntry /ga /n \\CS-SERVER\Nurses - Brother MFC-L8900CDW` — added machine-level printer
- GPP Shortcuts CSE discovery: `Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions"` revealed `{C418DD9D-...}` = "Group Policy Shortcuts"
- `gpresult /scope computer /r` confirmed applied GPOs: CSC - Caregiver Device Lockdown, CSC - Always Wait For Network, CSC - Reception Workstation Policy, CSC - Point and Print
## Pending / Incomplete Tasks
1. **App restriction for caregivers (INCOMPLETE):** UI restrictions block CMD/PowerShell/Settings/Control Panel/Run/Task Manager/Store, but Store apps (Camera, Netflix, Xbox, Spotify) are still launchable. Howard rejected removing apps from the machine (non-caregivers need them). Next step: AppLocker with Packaged App Deny rules scoped to SG-Caregivers — `Allow Domain Users: *` (baseline) + `Deny SG-Caregivers: [Netflix, Camera, Xbox, etc.]`. Needs AppIdentity service enabled + AppLocker XML policy in the Lockdown GPO (Computer Configuration).
2. **ASSISTNURSE-PC:** Second nurse station not yet configured. Needs: move from CN=Computers to OU=Caregiver Devices + deploy machine-level printers + gpupdate. GPO settings will apply automatically.
3. **PRT verification:** After token cache clear + reboot, need to confirm `AzureAdPrt: YES` on next caregiver login and verify ALIS SSO is fully silent (no password prompt in browser).
4. **`CSC - Reception Workstation Policy`:** Still applies to NURSESTATION-PC (pre-existing, flagged to Howard, unresolved).
5. **Cleanup after pilot:** Delete `pilot.test` AD account + delta sync when WS3 caregiver go-live is complete.
6. **Carried from earlier session:** break-glass accounts + FIDO2, caregiver allow-list flip, relicense 29 suspended-Standard, image backup repair, domain-join tail, network tail, WS8 SharePoint/Teams, WS9 Medtelligent scoping, ticket-verify pass.
## Reference Information
- Session log (earlier today): `clients/cascades-tucson/session-logs/2026-07/2026-07-17-howard-roadmap-finish-line-refresh.md`
- Kiosk GPO SYSVOL: `\\cascades.local\SYSVOL\cascades.local\Policies\{32d76052-4d92-446c-95fb-614653f84742}`
- Shortcuts XML: `...\User\Preferences\Shortcuts\Shortcuts.xml` (3 entries: ALIS, PharmCare, Helpany)
- Vault pilot.test: `clients/cascades-tucson/pilot-test-ad.sops.yaml`
- Vault (superseded cloud-only): `clients/cascades-tucson/pilot-test-user.sops.yaml`
- Phone kiosk config (Intune): `CSC - Android Shared Phones Restrictions` id `070a76c2-a8c3-4f7f-9ba7-1f4ac5084184`
- 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)

View File

@@ -19,6 +19,8 @@ Categories (the `[type]` tag): _(none)_ = skill/command execution failure ·
<!-- Append entries below this line --> <!-- Append entries below this line -->
2026-07-17 | Howard-Home | coord | coord API call failed (HTTP 422) [ctx: http=422 cmd=todo done resp={"error": "Request validation failed", "details": {"validation_errors": [{"field]
2026-07-17 | GURU-5070 | remediation-tool/exchange | [correction] Repeatedly used investigator-exo tier for Exchange REST -> 401 on every adminapi call (Security Investigator app lacks Exchange.ManageAsApp). Correct tier is exchange-op (only app with both Exchange.ManageAsApp + Exchange Admin role). Mike's 6th time hitting this. Fixed docs (SKILL.md, gotchas.md) + user-breach-check.sh (was using investigator-exo -> mailbox delegate/forwarding checks silently returned empty on every breach check) + memory reference_exchange_online_exchangeop_tier. [ctx: tenant=azcomputerguru.com ref=reference_exchange_online_exchangeop_tier] 2026-07-17 | GURU-5070 | remediation-tool/exchange | [correction] Repeatedly used investigator-exo tier for Exchange REST -> 401 on every adminapi call (Security Investigator app lacks Exchange.ManageAsApp). Correct tier is exchange-op (only app with both Exchange.ManageAsApp + Exchange Admin role). Mike's 6th time hitting this. Fixed docs (SKILL.md, gotchas.md) + user-breach-check.sh (was using investigator-exo -> mailbox delegate/forwarding checks silently returned empty on every breach check) + memory reference_exchange_online_exchangeop_tier. [ctx: tenant=azcomputerguru.com ref=reference_exchange_online_exchangeop_tier]
2026-07-17 | GURU-5070 | vault/secret-echo | [friction] grep filter to redact vault output missed the JSON field 'private_key' (filter had 'key:' with colon + 'apikey', not bare 'private_key') -> SA private key printed to transcript. Fix: when displaying vault entries, allowlist known plaintext fields (name/status/username/notes/url) instead of denylisting secret patterns; or pipe through 'sops -d' with an explicit field select. [ctx: ref=vault-skill file=msp-tools/acg-msp-access-google-workspace.sops.yaml] 2026-07-17 | GURU-5070 | vault/secret-echo | [friction] grep filter to redact vault output missed the JSON field 'private_key' (filter had 'key:' with colon + 'apikey', not bare 'private_key') -> SA private key printed to transcript. Fix: when displaying vault entries, allowlist known plaintext fields (name/status/username/notes/url) instead of denylisting secret patterns; or pipe through 'sops -d' with an explicit field select. [ctx: ref=vault-skill file=msp-tools/acg-msp-access-google-workspace.sops.yaml]