# Build "CSC - Caregiver Workstation" GPO (User-config GPP): desktop shortcuts + CS-SERVER printers. # Run on CS-SERVER (DC) as an account with AD/GP write rights. Idempotent-ish (recreates XML + attrs). # Cascades of Tucson - 2026-06-05. Mirrors production; test-filtered to SG-Caregivers-Test (set in step C). $ErrorActionPreference = 'Stop' Import-Module GroupPolicy -ErrorAction Stop Import-Module ActiveDirectory -ErrorAction Stop $gpoName = 'CSC - Caregiver Workstation' $domain = 'cascades.local' $changed = (Get-Date).ToString('yyyy-MM-dd HH:mm:ss') # 1) Create (or reuse) the GPO $gpo = Get-GPO -Name $gpoName -ErrorAction SilentlyContinue if (-not $gpo) { $gpo = New-GPO -Name $gpoName -Comment 'Caregiver/medtech desktop shortcuts (ALIS, LinkRx, Safe Living) + CS-SERVER printers. User GPP. TEST=filter SG-Caregivers-Test; go-live=filter SG-Caregivers.' Write-Output ('CREATED GPO: ' + $gpoName) } else { Write-Output ('REUSING GPO: ' + $gpoName) } $gid = '{' + $gpo.Id.ToString().ToUpper() + '}' Write-Output ('GUID: ' + $gid) # Disable the (unused) computer side $gpo.GpoStatus = 'ComputerSettingsDisabled' Write-Output ('GpoStatus: ' + $gpo.GpoStatus) # 2) Build Printers.xml function PrinterXml($share,$action,$default,$comment,$filters) { $p = '\\CS-SERVER\' + $share $uid = '{' + ([guid]::NewGuid()).ToString().ToUpper() + '}' return '' + $filters + '' } $noFilter = '' function GroupFilterXml($grp) { return '' } $entries = @() foreach ($s in 'NursesPrinter','HealthServices','MCMedTech','MCReception','MCDirector','CopyRoom') { $entries += (PrinterXml $s 'U' '0' '' $noFilter) } # Conditional defaults by DEVICE location (computer group membership, userContext=0) $entries += (PrinterXml 'NursesPrinter' 'U' '1' 'Default for Main Tower devices' (GroupFilterXml 'SG-PC-MainTower')) $entries += (PrinterXml 'MCMedTech' 'U' '1' 'Default for Memory Care devices' (GroupFilterXml 'SG-PC-MemoryCare')) $printersXml = '' + "`r`n" + '' + ($entries -join '') + '' # 3) Build Shortcuts.xml (URL internet shortcuts on the Desktop) function ShortcutXml($name,$url,$comment) { $uid = '{' + ([guid]::NewGuid()).ToString().ToUpper() + '}' return '' } $scs = @() $scs += (ShortcutXml 'ALIS' 'https://cascadestucson.alisonline.com/Login' 'ALIS EHR') $scs += (ShortcutXml 'LinkRx' 'https://pharmcare.linkrxnow.com/Login.aspx' 'LinkRx Pharmacy') $scs += (ShortcutXml 'Helpany' 'https://app.safe-living.com/login' 'Helpany (Safe Living)') $shortcutsXml = '' + "`r`n" + '' + ($scs -join '') + '' # 3b) Build Registry.xml: HKCU LegacyDefaultPrinterMode=1 (stop Windows "manage my default printer" so Nurses default sticks) function RegDword($key,$valName,$dword) { $uid = '{' + ([guid]::NewGuid()).ToString().ToUpper() + '}' return '' } $regItems = @() $regItems += (RegDword 'Software\Microsoft\Windows NT\CurrentVersion\Windows' 'LegacyDefaultPrinterMode' '00000001') $registryXml = '' + "`r`n" + '' + ($regItems -join '') + '' # 4) Write XML into SYSVOL (UTF-8 no BOM) $base = "C:\Windows\SYSVOL\sysvol\$domain\Policies\$gid" $pDir = Join-Path $base 'User\Preferences\Printers' $sDir = Join-Path $base 'User\Preferences\Shortcuts' New-Item -ItemType Directory -Path $pDir -Force | Out-Null New-Item -ItemType Directory -Path $sDir -Force | Out-Null $utf8 = New-Object System.Text.UTF8Encoding($false) [System.IO.File]::WriteAllText((Join-Path $pDir 'Printers.xml'), $printersXml, $utf8) [System.IO.File]::WriteAllText((Join-Path $sDir 'Shortcuts.xml'), $shortcutsXml, $utf8) $rDir = Join-Path $base 'User\Preferences\Registry' New-Item -ItemType Directory -Path $rDir -Force | Out-Null [System.IO.File]::WriteAllText((Join-Path $rDir 'Registry.xml'), $registryXml, $utf8) Write-Output ('WROTE: ' + (Join-Path $pDir 'Printers.xml')) Write-Output ('WROTE: ' + (Join-Path $sDir 'Shortcuts.xml')) Write-Output ('WROTE: ' + (Join-Path $rDir 'Registry.xml')) # 5) Register the GPP client-side extensions (user) + bump version (AD + GPT.ini must match) # CSE GUIDs MUST stay sorted ascending: 00000000 < B087BE9D(Registry) < BC75B1ED(Printers) < C418DD9D(Shortcuts) $cse = '[{00000000-0000-0000-0000-000000000000}{A8C42CEA-CDB8-4388-97F4-5831F933DA84}][{B087BE9D-ED37-454f-AF9C-04291E351182}{A8C42CEA-CDB8-4388-97F4-5831F933DA84}][{BC75B1ED-5833-4858-9BB8-CBF0B166DF9D}{A8C42CEA-CDB8-4388-97F4-5831F933DA84}][{C418DD9D-0D14-4efb-8FBF-CFE535C8FAC7}{A8C42CEA-CDB8-4388-97F4-5831F933DA84}]' $ver = 131072 # 0x00020000 = user version 2, computer version 0 $gpoDn = 'CN=' + $gid + ',CN=Policies,CN=System,DC=cascades,DC=local' Set-ADObject -Identity $gpoDn -Replace @{ gPCUserExtensionNames = $cse; versionNumber = $ver } $gptIni = Join-Path $base 'GPT.ini' $ini = Get-Content $gptIni -Raw if ($ini -match 'Version=\d+') { $ini = $ini -replace 'Version=\d+', ('Version=' + $ver) } else { $ini = $ini.TrimEnd() + "`r`nVersion=$ver`r`n" } Set-Content -Path $gptIni -Value $ini -Encoding ASCII Write-Output ('Set gPCUserExtensionNames + versionNumber=' + $ver + ' (AD + GPT.ini)') # 6) Verify Write-Output '' Write-Output '===== VERIFY =====' $chk = Get-ADObject -Identity $gpoDn -Properties gPCUserExtensionNames,versionNumber Write-Output ('gPCUserExtensionNames: ' + $chk.gPCUserExtensionNames) Write-Output ('versionNumber(AD): ' + $chk.versionNumber) Write-Output ('GPT.ini: ' + ((Get-Content $gptIni -Raw).Trim())) Write-Output '--- Printers.xml ---' Get-Content (Join-Path $pDir 'Printers.xml') -Raw Write-Output '--- Shortcuts.xml ---' Get-Content (Join-Path $sDir 'Shortcuts.xml') -Raw Write-Output '--- Registry.xml ---' Get-Content (Join-Path $rDir 'Registry.xml') -Raw