Major work from 2026-04-23: Folder redirection (OU=Life Enrichment): - Added 5 folders (Desktop, Pictures, Music, Videos, Favorites) to CSC - Folder Redirection (LE) alongside existing Documents + Downloads. All use Flags=1021 (Basic + create folder per user + move contents + policy-removal: redirect back). - Created CSC - Always Wait For Network GPO, linked at OU=Workstations. Disables FLO via correct Winlogon registry path (HKLM\Software\Policies\Microsoft\ Windows NT\CurrentVersion\Winlogon\SyncForegroundPolicy=1). First attempt used wrong path (Windows\System) which Winlogon ignored. - Proved GPO FR works for clean-hive users (test user LE.FRTest, now removed). - Wrote susan-profile-fix.ps1 to repair ProfWiz-poisoned profiles: robocopies local content to \CS-SERVER\homes\<user>, loads NTUSER.DAT, rewrites User Shell Folders (legacy + modern GUIDs) to UNC, unloads. Applied to Susan Hicks, verified via live SMB session + content access. Share access review doc: - share-access-matrix-2026-04-23.md drafted for John/Meredith review. One short block per employee (department + position + folders they can access). All settled decisions from today's calls captured (Sandra Fish = Meredith- only, Culinary = kitchen + M/J/A, no chat share, caregivers zero on-prem, Veronica = Meredith tier, CasAdmin201 retired, pacs empty). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
137 lines
6.5 KiB
PowerShell
137 lines
6.5 KiB
PowerShell
# ============================================================================
|
|
# Susan Hicks profile fix — runs on DESKTOP-ROK7VNM as SYSTEM via GuruRMM.
|
|
#
|
|
# Preconditions:
|
|
# - Susan is signed out (NTUSER.DAT unlocked)
|
|
# - FLO-off GPO active (SyncForegroundPolicy at Winlogon path)
|
|
# - LE FR GPO has working UNC paths on SYSVOL
|
|
#
|
|
# Caller injects sysadmin password into $adminPass placeholder at the top.
|
|
# SYSTEM on ROK7VNM has full local file access, but can't auth to
|
|
# \\CS-SERVER\homes as itself — so we 'net use' a drive letter with
|
|
# CASCADES\sysadmin, do the copy, then drop it.
|
|
# ============================================================================
|
|
|
|
$ErrorActionPreference = 'Continue'
|
|
|
|
$adminUser = 'CASCADES\sysadmin'
|
|
$adminPass = '__ADMIN_PASS__'
|
|
$user = 'Susan.Hicks'
|
|
$localRoot = 'C:\Users\SusanH'
|
|
$serverUNC = '\\CS-SERVER\homes'
|
|
$userUNC = $serverUNC + '\' + $user
|
|
$driveLetter = 'X'
|
|
|
|
Write-Host '=== Pre-checks ===' -ForegroundColor Cyan
|
|
if (-not (Test-Path $localRoot)) { throw "No local profile at $localRoot" }
|
|
$nt = Join-Path $localRoot 'NTUSER.DAT'
|
|
if (-not (Test-Path $nt)) { throw "No NTUSER.DAT at $nt" }
|
|
|
|
try {
|
|
$s = [System.IO.File]::Open($nt, 'Open', 'Read', 'None')
|
|
$s.Close()
|
|
Write-Host '[OK] NTUSER.DAT is unlocked (Susan is signed out)' -ForegroundColor Green
|
|
} catch {
|
|
throw "NTUSER.DAT is LOCKED — Susan must be signed out. Error: $($_.Exception.Message)"
|
|
}
|
|
|
|
# ------------- Step 1: map homes share with sysadmin creds -------------
|
|
Write-Host "`n=== Step 1: Mount \\CS-SERVER\homes as ${driveLetter}: ===" -ForegroundColor Cyan
|
|
# Clean up any stale mapping (ignore failure if none existed)
|
|
cmd.exe /c "net use ${driveLetter}: /delete /y >nul 2>&1"
|
|
$mapOut = cmd.exe /c "net use ${driveLetter}: $serverUNC $adminPass /user:$adminUser 2>&1"
|
|
if ($LASTEXITCODE -ne 0) { throw "net use failed: $mapOut" }
|
|
Write-Host "[OK] Mapped $driveLetter to $serverUNC as $adminUser"
|
|
|
|
try {
|
|
# ensure per-user home exists
|
|
$driveHome = "${driveLetter}:\$user"
|
|
if (-not (Test-Path $driveHome)) { New-Item -Path $driveHome -ItemType Directory -Force | Out-Null }
|
|
|
|
# ------------- Step 2: robocopy local content to server -------------
|
|
Write-Host "`n=== Step 2: Copy local folders to $userUNC ===" -ForegroundColor Cyan
|
|
$folders = @('Documents','Desktop','Downloads','Pictures','Music','Videos','Favorites')
|
|
foreach ($f in $folders) {
|
|
$from = Join-Path $localRoot $f
|
|
$to = Join-Path $driveHome $f
|
|
if (-not (Test-Path $from)) { Write-Host " [SKIP] $from does not exist"; continue }
|
|
if (-not (Test-Path $to)) { New-Item -Path $to -ItemType Directory -Force | Out-Null }
|
|
|
|
$rbArgs = @($from, $to, '/E', '/COPY:DAT', '/DCOPY:T', '/XJ', '/R:1', '/W:1',
|
|
'/MT:8', '/NFL', '/NDL', '/NJH', '/NJS')
|
|
& robocopy.exe @rbArgs | Out-Null
|
|
$code = $LASTEXITCODE
|
|
$srcCount = (Get-ChildItem $from -Force -Recurse -File -ErrorAction SilentlyContinue | Measure-Object).Count
|
|
$dstCount = (Get-ChildItem $to -Force -Recurse -File -ErrorAction SilentlyContinue | Measure-Object).Count
|
|
$tag = if ($code -ge 8) { '[FAIL]' } else { '[OK] ' }
|
|
Write-Host " $tag $f : src=$srcCount dst=$dstCount (robocopy exit=$code)"
|
|
}
|
|
|
|
Write-Host "`n=== Server-side Susan.Hicks after copy ===" -ForegroundColor Cyan
|
|
Get-ChildItem $driveHome -Force -Directory |
|
|
Select Name, @{N='Items';E={(Get-ChildItem $_.FullName -Force -Recurse -File -ErrorAction SilentlyContinue | Measure-Object).Count}} |
|
|
Format-Table -AutoSize
|
|
|
|
} finally {
|
|
# always drop the mapped drive (ignore failure)
|
|
cmd.exe /c "net use ${driveLetter}: /delete /y >nul 2>&1"
|
|
}
|
|
|
|
# ------------- Step 3: load Susan's NTUSER.DAT -------------
|
|
Write-Host "`n=== Step 3: Load Susan's NTUSER.DAT as HKU\SusanTemp ===" -ForegroundColor Cyan
|
|
cmd.exe /c "reg.exe unload HKU\SusanTemp >nul 2>&1" # clean up any prior
|
|
$loadOut = cmd.exe /c "reg.exe load HKU\SusanTemp `"$nt`" 2>&1"
|
|
if ($LASTEXITCODE -ne 0) { throw "reg load failed: $loadOut" }
|
|
Write-Host '[OK] Hive loaded'
|
|
|
|
try {
|
|
# ------------- Step 4: rewrite User Shell Folders -------------
|
|
Write-Host "`n=== Step 4: Rewrite User Shell Folders to UNC ===" -ForegroundColor Cyan
|
|
$usf = 'Registry::HKEY_USERS\SusanTemp\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders'
|
|
$sf = 'Registry::HKEY_USERS\SusanTemp\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders'
|
|
|
|
$mapLegacy = @{
|
|
'Desktop' = "$userUNC\Desktop"
|
|
'Personal' = "$userUNC\Documents"
|
|
'My Pictures' = "$userUNC\Pictures"
|
|
'My Music' = "$userUNC\Music"
|
|
'My Video' = "$userUNC\Videos"
|
|
'Favorites' = "$userUNC\Favorites"
|
|
}
|
|
$mapGuid = @{
|
|
'{B4BFCC3A-DB2C-424C-B029-7FE99A87C641}' = "$userUNC\Desktop"
|
|
'{FDD39AD0-238F-46AF-ADB4-6C85480369C7}' = "$userUNC\Documents"
|
|
'{374DE290-123F-4565-9164-39C4925E467B}' = "$userUNC\Downloads"
|
|
'{7D83EE9B-2244-4E70-B1F5-5393042AF1E4}' = "$userUNC\Downloads"
|
|
'{33E28130-4E1E-4676-835A-98395C3BC3BB}' = "$userUNC\Pictures"
|
|
'{4BD8D571-6D19-48D3-BE97-422220080E43}' = "$userUNC\Music"
|
|
'{18989B1D-99B5-455B-841C-AB7C74E4DDFC}' = "$userUNC\Videos"
|
|
'{35286A68-3C57-41A1-BBB1-0EAE73D76C95}' = "$userUNC\Videos"
|
|
'{1777F761-68AD-4D8A-87BD-30B759FA33DD}' = "$userUNC\Favorites"
|
|
'{F42EE2D3-909F-4907-8871-4C22FC0BF756}' = "$userUNC\Documents"
|
|
}
|
|
|
|
foreach ($k in $mapLegacy.Keys) {
|
|
Set-ItemProperty -LiteralPath $usf -Name $k -Value $mapLegacy[$k] -Type ExpandString
|
|
Set-ItemProperty -LiteralPath $sf -Name $k -Value $mapLegacy[$k] -ErrorAction SilentlyContinue
|
|
Write-Host " $k = $($mapLegacy[$k])"
|
|
}
|
|
foreach ($g in $mapGuid.Keys) {
|
|
Set-ItemProperty -LiteralPath $usf -Name $g -Value $mapGuid[$g] -Type ExpandString
|
|
Write-Host " $g = $($mapGuid[$g])"
|
|
}
|
|
|
|
Write-Host "`n=== Verify final User Shell Folders ===" -ForegroundColor Cyan
|
|
Get-ItemProperty -LiteralPath $usf | Select * -ExcludeProperty PS* | Format-List | Out-String | Write-Host
|
|
|
|
} finally {
|
|
Write-Host "`n=== Step 5: Unload hive ===" -ForegroundColor Cyan
|
|
[gc]::Collect()
|
|
Start-Sleep -Seconds 1
|
|
cmd.exe /c "reg.exe unload HKU\SusanTemp >nul 2>&1"
|
|
Write-Host '[OK] Hive unloaded'
|
|
}
|
|
|
|
Write-Host "`n=== DONE ===" -ForegroundColor Green
|
|
Write-Host "Next: sign out LE.FRTest, sign in as Susan. Shell will pull UNC paths from hive; all content pre-copied to server."
|