#Requires -RunAsAdministrator <# .SYNOPSIS Phase 2.2: AD cleanup and preparation on CS-SERVER. .DESCRIPTION Fixes OU naming, creates Workstations OU, creates security groups with members, removes stale/former accounts, fixes group issues, and moves computers. Run on CS-SERVER via ScreenConnect. .NOTES PREREQUISITE: Run phase2-ou-cleanup.ps1 FIRST to remove duplicate root-level OUs. Client has confirmed all account removals. Set $DeleteAccounts = $true when ready to execute deletions. #> Import-Module ActiveDirectory -ErrorAction Stop # --- SAFETY FLAG --- $DeleteAccounts = $false $Domain = "DC=cascades,DC=local" Write-Host "=== Phase 2.2: AD Cleanup & Preparation ===" -ForegroundColor Cyan Write-Host "" # ============================================================ # STEP 1: Fix immediate security issues # ============================================================ Write-Host "--- Fixing Security Issues ---" -ForegroundColor Yellow # Remove disabled Monica.Ramirez from Domain Admins try { $monica = Get-ADUser -Identity "Monica.Ramirez" -ErrorAction SilentlyContinue if ($monica) { Remove-ADGroupMember -Identity "Domain Admins" -Members "Monica.Ramirez" -Confirm:$false -ErrorAction Stop Write-Host " [OK] Removed Monica.Ramirez from Domain Admins" -ForegroundColor Green } } catch { Write-Host " [SKIP] Monica.Ramirez not in Domain Admins or not found" -ForegroundColor DarkGray } # Disable Haris.Durut (currently enabled, no longer employed) try { Disable-ADAccount -Identity "Haris.Durut" -ErrorAction Stop Write-Host " [OK] Disabled Haris.Durut" -ForegroundColor Green } catch { Write-Host " [SKIP] Haris.Durut already disabled or not found" -ForegroundColor DarkGray } # ============================================================ # STEP 2: Fix misspelled OU # ============================================================ Write-Host "`n--- Fixing misspelled OU ---" -ForegroundColor Yellow try { $mgmtOU = Get-ADOrganizationalUnit -Filter 'Name -eq "Managment"' -ErrorAction SilentlyContinue if ($mgmtOU) { Rename-ADOrganizationalUnit -Identity $mgmtOU.DistinguishedName -NewName "Management" Write-Host " [OK] Renamed 'Managment' -> 'Management'" -ForegroundColor Green } else { Write-Host " [SKIP] 'Managment' OU not found (already renamed?)" -ForegroundColor DarkGray } } catch { Write-Host " [ERROR] Failed to rename OU: $_" -ForegroundColor Red } # Fix "Quickboosk acccess" group name typo try { $qbGroup = Get-ADGroup -Filter 'Name -eq "Quickboosk acccess"' -ErrorAction SilentlyContinue if ($qbGroup) { Rename-ADObject -Identity $qbGroup.DistinguishedName -NewName "QuickBooks Access" Set-ADGroup -Identity $qbGroup.DistinguishedName -DisplayName "QuickBooks Access" Write-Host " [OK] Renamed 'Quickboosk acccess' -> 'QuickBooks Access'" -ForegroundColor Green } else { Write-Host " [SKIP] 'Quickboosk acccess' group not found" -ForegroundColor DarkGray } } catch { Write-Host " [ERROR] Failed to rename QuickBooks group: $_" -ForegroundColor Red } # Add lauren.hasselman to QuickBooks Access (she replaced Jeff Bristol) try { $qbGroupName = "QuickBooks Access" # Try both names in case rename hasn't run yet $qb = Get-ADGroup -Filter "Name -eq '$qbGroupName'" -ErrorAction SilentlyContinue if (-not $qb) { $qb = Get-ADGroup -Filter 'Name -eq "Quickboosk acccess"' -ErrorAction SilentlyContinue } if ($qb) { Add-ADGroupMember -Identity $qb -Members "lauren.hasselman" -ErrorAction Stop Write-Host " [OK] Added lauren.hasselman to $($qb.Name)" -ForegroundColor Green } } catch { Write-Host " [SKIP] lauren.hasselman already in QuickBooks group or error: $_" -ForegroundColor DarkGray } # ============================================================ # STEP 3: Create Workstations OU # ============================================================ Write-Host "`n--- Creating Workstations OU ---" -ForegroundColor Yellow $ous = @( @{ Name = "Workstations"; Path = $Domain } @{ Name = "Staff PCs"; Path = "OU=Workstations,$Domain" } @{ Name = "Shared PCs"; Path = "OU=Workstations,$Domain" } ) foreach ($ou in $ous) { try { $existing = Get-ADOrganizationalUnit -Filter "Name -eq '$($ou.Name)'" -SearchBase $ou.Path -SearchScope OneLevel -ErrorAction SilentlyContinue if (-not $existing) { New-ADOrganizationalUnit -Name $ou.Name -Path $ou.Path -ProtectedFromAccidentalDeletion $true Write-Host " [OK] Created OU=$($ou.Name) in $($ou.Path)" -ForegroundColor Green } else { Write-Host " [SKIP] OU=$($ou.Name) already exists" -ForegroundColor DarkGray } } catch { Write-Host " [ERROR] Failed to create $($ou.Name): $_" -ForegroundColor Red } } # ============================================================ # STEP 4: Create security groups and populate members # ============================================================ Write-Host "`n--- Creating & Populating Security Groups ---" -ForegroundColor Yellow # Group definitions: Name -> array of AD SamAccountNames $groupDefs = @{ "SG-Management-RW" = @( "Meredith.Kuhn", "Ashley.Jensen", "Megan.Hiatt", "Crystal.Rodriguez", "Tamra.Matthews", "britney.thompson", "Veronica.Feller", "strozzi", "Alyssa.Brooks", "lauren.hasselman" ) "SG-Sales-RW" = @( "Megan.Hiatt", "Crystal.Rodriguez", "Tamra.Matthews" ) "SG-Server-RW" = @( "Ashley.Jensen", "britney.thompson", "Christina.DuPras", "Veronica.Feller", "Meredith.Kuhn" ) "SG-Chat-RW" = @( "Ashley.Jensen", "britney.thompson", "Veronica.Feller" ) "SG-Culinary-RW" = @( "JD.Martin", "Ramon.Castaneda", "Alyssa.Brooks" ) "SG-IT-RW" = @( "howard", "sysadmin" ) "SG-Receptionist-RW" = @( "Cathy.Kingston", "Shontiel.Nunn", "Ray.Rai", "Sebastian.Leon", "Michelle.Shestko" ) "SG-Directory-RW" = @( "Cathy.Kingston", "Shontiel.Nunn", "Christina.DuPras" ) "SG-Public-RW" = @() # Empty — will use "Authenticated Users" at share level "SG-AllShares-RO" = @() # Populated as needed } foreach ($g in $groupDefs.Keys) { # Create group if it doesn't exist try { $existing = Get-ADGroup -Filter "Name -eq '$g'" -ErrorAction SilentlyContinue if (-not $existing) { New-ADGroup -Name $g -GroupScope DomainLocal -GroupCategory Security -Path $Domain ` -Description "File share access - created during migration" Write-Host " [OK] Created group: $g" -ForegroundColor Green } else { Write-Host " [SKIP] Group $g already exists" -ForegroundColor DarkGray } } catch { Write-Host " [ERROR] Failed to create $g : $_" -ForegroundColor Red continue } # Add members foreach ($member in $groupDefs[$g]) { try { Add-ADGroupMember -Identity $g -Members $member -ErrorAction Stop Write-Host " [OK] Added $member to $g" -ForegroundColor Green } catch { Write-Host " [SKIP] $member -> $g (already member or not found)" -ForegroundColor DarkGray } } } # ============================================================ # STEP 5: Delete stale and former employee accounts # ============================================================ Write-Host "`n--- Removing Stale & Former Employee Accounts ---" -ForegroundColor Yellow # Already disabled — delete $disabledToDelete = @( "Anna.Pitzlin", "Nela.Durut-Azizi", "Jodi.Ramstack", "Monica.Ramirez", "jeff.bristol" ) # Currently enabled — disable first, then delete (former employees not in HR) $enabledToRemove = @( "Haris.Durut", "Nuria.Diaz", "Cathy.Reece", "Kelly.Wallace", "alyssa.brooks", "Isabella.Islas", "ann.dery" ) if ($DeleteAccounts) { Write-Host " Deleting disabled accounts..." -ForegroundColor Yellow foreach ($acct in $disabledToDelete) { try { Remove-ADUser -Identity $acct -Confirm:$false -ErrorAction Stop Write-Host " [OK] Deleted: $acct" -ForegroundColor Green } catch { Write-Host " [SKIP] $acct not found: $_" -ForegroundColor DarkGray } } Write-Host " Disabling and deleting former employees..." -ForegroundColor Yellow foreach ($acct in $enabledToRemove) { try { Disable-ADAccount -Identity $acct -ErrorAction SilentlyContinue Remove-ADUser -Identity $acct -Confirm:$false -ErrorAction Stop Write-Host " [OK] Disabled + Deleted: $acct" -ForegroundColor Green } catch { Write-Host " [SKIP] $acct not found: $_" -ForegroundColor DarkGray } } } else { Write-Host " [WARN] Deletion SKIPPED - set `$DeleteAccounts = `$true to execute" -ForegroundColor Yellow Write-Host "" Write-Host " Disabled accounts to delete:" -ForegroundColor Yellow foreach ($acct in $disabledToDelete) { Write-Host " - $acct" -ForegroundColor DarkGray } Write-Host " Enabled accounts to disable + delete (NOT in HR):" -ForegroundColor Yellow foreach ($acct in $enabledToRemove) { Write-Host " - $acct" -ForegroundColor DarkGray } } # ============================================================ # STEP 6: Remove shared/generic accounts from active use # ============================================================ Write-Host "`n--- Shared Account Cleanup ---" -ForegroundColor Yellow $sharedAccounts = @("Culinary", "Receptionist", "saleshare", "directoryshare") Write-Host " The following shared accounts should be replaced with individual logins:" -ForegroundColor Yellow foreach ($acct in $sharedAccounts) { try { $user = Get-ADUser -Identity $acct -Properties Enabled -ErrorAction SilentlyContinue if ($user -and $user.Enabled) { Write-Host " $acct — ENABLED (disable after users have individual accounts)" -ForegroundColor Yellow } } catch { Write-Host " $acct — not found" -ForegroundColor DarkGray } } # ============================================================ # STEP 7: Move computers to Workstations OU # ============================================================ Write-Host "`n--- Moving Computers to Workstations OU ---" -ForegroundColor Yellow $targetOU = "OU=Staff PCs,OU=Workstations,$Domain" # Note: CS-QB stays in CN=Computers — it's a Hyper-V VM (VoIP server), not a staff PC $computers = @("CRYSTAL-PC", "ACCT2-PC", "DESKTOP-H6QHRR7", "DESKTOP-1ISF081") foreach ($pc in $computers) { try { $comp = Get-ADComputer -Identity $pc -ErrorAction SilentlyContinue if ($comp) { if ($comp.DistinguishedName -notlike "*$targetOU*") { Move-ADObject -Identity $comp.DistinguishedName -TargetPath $targetOU Write-Host " [OK] Moved $pc to Staff PCs OU" -ForegroundColor Green } else { Write-Host " [SKIP] $pc already in Staff PCs OU" -ForegroundColor DarkGray } } else { Write-Host " [SKIP] $pc not found in AD" -ForegroundColor DarkGray } } catch { Write-Host " [ERROR] Failed to move $pc : $_" -ForegroundColor Red } } # ============================================================ # SUMMARY # ============================================================ Write-Host "`n=== AD Setup Summary ===" -ForegroundColor Cyan Write-Host "`nOU Structure:" -ForegroundColor Yellow Get-ADOrganizationalUnit -Filter * | Select-Object Name, DistinguishedName | Format-Table -AutoSize -Wrap Write-Host "Security Groups & Members:" -ForegroundColor Yellow Get-ADGroup -Filter 'Name -like "SG-*"' | ForEach-Object { $members = (Get-ADGroupMember $_ -ErrorAction SilentlyContinue | Select-Object -Expand Name) -join ", " Write-Host " $($_.Name): $members" -ForegroundColor Cyan } Write-Host "`nEnabled User Count:" -ForegroundColor Yellow $enabled = (Get-ADUser -Filter 'Enabled -eq $true').Count Write-Host " $enabled enabled accounts" -ForegroundColor Cyan Write-Host "`n=== AD Cleanup Complete ===" -ForegroundColor Cyan Write-Host "Next: Run phase2-sync-synology.ps1 to sync data from NAS" -ForegroundColor Green