Files
claudetools/.claude/temp/fix-homes-ntfs.ps1
Howard Enos 3a09746468 sync: auto-sync from HOWARD-HOME at 2026-05-20 22:41:35
Author: Howard Enos
Machine: HOWARD-HOME
Timestamp: 2026-05-20 22:41:35
2026-05-20 22:41:38 -07:00

110 lines
4.7 KiB
PowerShell

$homesPath = 'D:\Homes'
Write-Output "=== Fixing homes root NTFS permissions ==="
Write-Output "Root: $homesPath"
Write-Output ""
# --- Fix root ACL ---
# Remove BUILTIN\Users inherited permissions that flow down to all subfolders.
# Replace with CreateDirectories (This folder only) so users can create their own subfolder
# but cannot read siblings.
$acl = Get-Acl $homesPath
# Identify and remove BUILTIN\Users rules
$usersRulesToRemove = $acl.Access | Where-Object {
$_.IdentityReference.Value -eq 'BUILTIN\Users'
}
foreach ($rule in $usersRulesToRemove) {
$acl.RemoveAccessRule($rule) | Out-Null
Write-Output "[REMOVED] BUILTIN\Users | $($rule.FileSystemRights) | Inherit:$($rule.InheritanceFlags)"
}
# Add back the minimum: This Folder Only — just enough to create their own subfolder
# List Folder + Create Folders on this folder only (not inherited)
$thisOnly = [System.Security.AccessControl.InheritanceFlags]::None
$noProp = [System.Security.AccessControl.PropagationFlags]::None
$allow = [System.Security.AccessControl.AccessControlType]::Allow
# "Authenticated Users" list + create folders on this folder only
$minRights = [System.Security.AccessControl.FileSystemRights]'ReadAndExecute,Synchronize,CreateDirectories'
$minRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
'Authenticated Users', $minRights, $thisOnly, $noProp, $allow
)
$acl.AddAccessRule($minRule)
Write-Output "[ADDED] Authenticated Users | ReadAndExecute+CreateDirectories | This Folder Only"
Set-Acl -Path $homesPath -AclObject $acl
Write-Output "[OK] Root ACL updated"
Write-Output ""
# --- Fix each existing user subfolder ---
# Break inheritance, strip BUILTIN\Users, verify user has Full Control
Write-Output "=== Fixing existing user subfolder ACLs ==="
Get-ChildItem $homesPath -Directory -EA SilentlyContinue | ForEach-Object {
$folder = $_.FullName
$folderName = $_.Name
# Try to resolve folder name to a domain user
# Folder names like "Crystal.Rodriguez", "lauren.hasselman", etc.
$userName = $folderName
$domainUser = "CASCADES\$userName"
$subAcl = Get-Acl $folder
# Disable inheritance (convert inherited to explicit, then we remove what we don't want)
$subAcl.SetAccessRuleProtection($true, $true) # protect=true, preserveInherited=true
Set-Acl -Path $folder -AclObject $subAcl
# Re-read now that inheritance is broken
$subAcl = Get-Acl $folder
# Remove BUILTIN\Users entries
$toRemove = $subAcl.Access | Where-Object {
$_.IdentityReference.Value -eq 'BUILTIN\Users'
}
foreach ($rule in $toRemove) {
$subAcl.RemoveAccessRule($rule) | Out-Null
Write-Output " [$folderName] Removed BUILTIN\Users | $($rule.FileSystemRights)"
}
# Verify user has Full Control (if user account exists in domain)
$userExists = $subAcl.Access | Where-Object {
$_.IdentityReference.Value -like "*$userName*"
}
if (-not $userExists) {
# Check if we can resolve the user and add them
try {
$adUser = Get-ADUser -Filter "SamAccountName -eq '$userName'" -EA SilentlyContinue
if (-not $adUser) {
# Try case-insensitive match
$adUser = Get-ADUser -Filter "Name -like '$($userName.Replace('.','\s'))*'" -EA SilentlyContinue
}
if ($adUser) {
$fullCtrlRights = [System.Security.AccessControl.FileSystemRights]::FullControl
$allInherit = [System.Security.AccessControl.InheritanceFlags]'ContainerInherit,ObjectInherit'
$noProp2 = [System.Security.AccessControl.PropagationFlags]::None
$userRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
"CASCADES\$($adUser.SamAccountName)", $fullCtrlRights, $allInherit, $noProp2, $allow
)
$subAcl.AddAccessRule($userRule)
Write-Output " [$folderName] Added CASCADES\$($adUser.SamAccountName) | FullControl"
} else {
Write-Output " [$folderName] WARNING: no user found for '$userName' — folder has no explicit user ACE"
}
} catch {
Write-Output " [$folderName] WARNING: AD lookup failed: $($_.Exception.Message)"
}
} else {
Write-Output " [$folderName] User ACE already present: $($userExists[0].IdentityReference)"
}
Set-Acl -Path $folder -AclObject $subAcl
Write-Output " [$folderName] ACL updated [OK]"
Write-Output ""
}
Write-Output "=== Final root ACL ==="
(Get-Acl $homesPath).Access | ForEach-Object {
Write-Output " $($_.IdentityReference) | $($_.FileSystemRights) | Inherit:$($_.InheritanceFlags) Prop:$($_.PropagationFlags)"
}