#Requires -RunAsAdministrator
<#
.SYNOPSIS
    Phase 2.1: OU Structure Cleanup on CS-SERVER.
.DESCRIPTION
    Audits and removes duplicate/empty root-level OUs, fixes misspelling,
    handles CN=Users account cleanup. Run BEFORE phase2-ad-setup.ps1.
    Run on CS-SERVER via ScreenConnect.
.NOTES
    Step 1: Read-only audit (always runs)
    Step 2: Delete duplicate root OUs (requires $DeleteOUs = $true)
    Step 3: Delete empty Managment/MemCare/Sales OUs (requires $DeleteOUs = $true)
    Step 4: Delete/disable stale accounts in CN=Users (requires $DeleteAccounts = $true)
    Step 5: Flag Lupe.Sanchez for review
#>

Import-Module ActiveDirectory -ErrorAction Stop

# --- SAFETY FLAGS ---
$DeleteOUs      = $false   # Set $true to delete empty root-level OUs
$DeleteAccounts = $false   # Set $true to delete/disable stale accounts in CN=Users

$Domain = "DC=cascades,DC=local"

Write-Host "=== Phase 2.1: OU Structure Cleanup ===" -ForegroundColor Cyan
Write-Host ""

# ============================================================
# STEP 1: Audit root-level duplicate OUs (READ-ONLY)
# ============================================================
Write-Host "--- Step 1: Auditing Root-Level Duplicate OUs ---" -ForegroundColor Yellow
Write-Host "These OUs exist at root AND under Departments. Root copies should be empty." -ForegroundColor DarkGray
Write-Host ""

$rootDuplicateOUs = @(
    "OU=Administrative,$Domain",
    "OU=Care-Assisted Living,$Domain",
    "OU=Care-Memorycare,$Domain",
    "OU=Culinary,$Domain",
    "OU=Housekeeping,$Domain",
    "OU=Life Enrichment,$Domain",
    "OU=Maintenance,$Domain",
    "OU=Marketing,$Domain",
    "OU=Resident Services,$Domain",
    "OU=Transportation,$Domain"
)

$allEmpty = $true
$ouResults = @{}

foreach ($ou in $rootDuplicateOUs) {
    $ouName = ($ou -split ',')[0] -replace 'OU=',''
    try {
        $objects = Get-ADObject -SearchBase $ou -SearchScope OneLevel -Filter * -ErrorAction Stop
        $props = Get-ADOrganizationalUnit $ou -Properties gPLink, ProtectedFromAccidentalDeletion -ErrorAction Stop

        Write-Host "  === $ouName (root) ===" -ForegroundColor White
        if ($objects) {
            $allEmpty = $false
            $ouResults[$ou] = "HAS_OBJECTS"
            foreach ($obj in $objects) {
                Write-Host "    $($obj.ObjectClass): $($obj.Name)" -ForegroundColor Red
            }
        } else {
            $ouResults[$ou] = "EMPTY"
            Write-Host "    Empty" -ForegroundColor Green
        }

        $gpLink = if ($props.gPLink) { $props.gPLink } else { "(none)" }
        Write-Host "    GPLink: $gpLink" -ForegroundColor DarkGray
        Write-Host "    Protected: $($props.ProtectedFromAccidentalDeletion)" -ForegroundColor DarkGray
        Write-Host ""
    }
    catch {
        Write-Host "  === $ouName (root) ===" -ForegroundColor White
        Write-Host "    NOT FOUND — may already be deleted" -ForegroundColor DarkGray
        $ouResults[$ou] = "NOT_FOUND"
        Write-Host ""
    }
}

# Also audit Managment, MemCare, Sales
Write-Host "--- Auditing Managment, MemCare, Sales Root OUs ---" -ForegroundColor Yellow
Write-Host ""

$miscRootOUs = @(
    "OU=Managment,$Domain",
    "OU=MemCare,$Domain",
    "OU=Sales,$Domain"
)

foreach ($ou in $miscRootOUs) {
    $ouName = ($ou -split ',')[0] -replace 'OU=',''
    try {
        $objects = Get-ADObject -SearchBase $ou -SearchScope OneLevel -Filter * -ErrorAction Stop
        $props = Get-ADOrganizationalUnit $ou -Properties gPLink, ProtectedFromAccidentalDeletion -ErrorAction Stop

        Write-Host "  === $ouName (root) ===" -ForegroundColor White
        if ($objects) {
            $allEmpty = $false
            $ouResults[$ou] = "HAS_OBJECTS"
            foreach ($obj in $objects) {
                Write-Host "    $($obj.ObjectClass): $($obj.Name)" -ForegroundColor Red
            }
        } else {
            $ouResults[$ou] = "EMPTY"
            Write-Host "    Empty" -ForegroundColor Green
        }

        $gpLink = if ($props.gPLink) { $props.gPLink } else { "(none)" }
        Write-Host "    GPLink: $gpLink" -ForegroundColor DarkGray
        Write-Host "    Protected: $($props.ProtectedFromAccidentalDeletion)" -ForegroundColor DarkGray
        Write-Host ""
    }
    catch {
        Write-Host "  === $ouName (root) ===" -ForegroundColor White
        Write-Host "    NOT FOUND — may already be deleted" -ForegroundColor DarkGray
        $ouResults[$ou] = "NOT_FOUND"
        Write-Host ""
    }
}

if ($allEmpty) {
    Write-Host "  All audited OUs are EMPTY — safe to delete." -ForegroundColor Green
} else {
    Write-Host "  WARNING: Some OUs contain objects! Review output above before deleting." -ForegroundColor Red
}
Write-Host ""

# ============================================================
# STEP 2: Delete root-level duplicate OUs (if empty)
# ============================================================
Write-Host "--- Step 2: Delete Root-Level Duplicate Department OUs ---" -ForegroundColor Yellow

if ($DeleteOUs) {
    foreach ($ou in $rootDuplicateOUs) {
        $ouName = ($ou -split ',')[0] -replace 'OU=',''
        if ($ouResults[$ou] -eq "EMPTY") {
            try {
                # Remove accidental deletion protection
                Set-ADOrganizationalUnit $ou -ProtectedFromAccidentalDeletion $false -ErrorAction Stop
                # Delete the OU
                Remove-ADOrganizationalUnit $ou -Confirm:$false -ErrorAction Stop
                Write-Host "  [OK] Deleted root-level OU: $ouName" -ForegroundColor Green
            }
            catch {
                Write-Host "  [ERROR] Failed to delete $ouName : $_" -ForegroundColor Red
            }
        }
        elseif ($ouResults[$ou] -eq "HAS_OBJECTS") {
            Write-Host "  [SKIP] $ouName has objects — move them to Departments\$ouName first!" -ForegroundColor Red
        }
        elseif ($ouResults[$ou] -eq "NOT_FOUND") {
            Write-Host "  [SKIP] $ouName already deleted" -ForegroundColor DarkGray
        }
    }
} else {
    Write-Host "  [WARN] Deletion SKIPPED — set `$DeleteOUs = `$true after reviewing audit output" -ForegroundColor Yellow
}
Write-Host ""

# ============================================================
# STEP 3: Delete empty Managment, MemCare, Sales root OUs
# ============================================================
Write-Host "--- Step 3: Delete Managment, MemCare, Sales Root OUs ---" -ForegroundColor Yellow

if ($DeleteOUs) {
    foreach ($ou in $miscRootOUs) {
        $ouName = ($ou -split ',')[0] -replace 'OU=',''
        if ($ouResults[$ou] -eq "EMPTY") {
            try {
                Set-ADOrganizationalUnit $ou -ProtectedFromAccidentalDeletion $false -ErrorAction Stop
                Remove-ADOrganizationalUnit $ou -Confirm:$false -ErrorAction Stop
                Write-Host "  [OK] Deleted root-level OU: $ouName" -ForegroundColor Green
            }
            catch {
                Write-Host "  [ERROR] Failed to delete $ouName : $_" -ForegroundColor Red
            }
        }
        elseif ($ouResults[$ou] -eq "HAS_OBJECTS") {
            Write-Host "  [SKIP] $ouName has objects — review and move/delete contents first!" -ForegroundColor Red
        }
        elseif ($ouResults[$ou] -eq "NOT_FOUND") {
            Write-Host "  [SKIP] $ouName already deleted" -ForegroundColor DarkGray
        }
    }
} else {
    Write-Host "  [WARN] Deletion SKIPPED — set `$DeleteOUs = `$true after reviewing audit output" -ForegroundColor Yellow
}
Write-Host ""

# ============================================================
# STEP 4: Handle stale accounts in CN=Users
# ============================================================
Write-Host "--- Step 4: CN=Users Account Cleanup ---" -ForegroundColor Yellow

# First, show what's in CN=Users
Write-Host "  Current accounts in CN=Users:" -ForegroundColor DarkGray
$usersContainer = "CN=Users,$Domain"
$cnUsers = Get-ADUser -SearchBase $usersContainer -SearchScope OneLevel -Filter * -Properties Enabled, Description, LastLogonDate
foreach ($u in $cnUsers | Sort-Object Enabled, Name) {
    $status = if ($u.Enabled) { "Enabled " } else { "Disabled" }
    $lastLogon = if ($u.LastLogonDate) { $u.LastLogonDate.ToString("yyyy-MM-dd") } else { "Never" }
    Write-Host "    [$status] $($u.SamAccountName) — Last logon: $lastLogon" -ForegroundColor $(if ($u.Enabled) { "White" } else { "DarkGray" })
}
Write-Host ""

# Already disabled — delete immediately
$disabledToDelete = @(
    "Anna.Pitzlin",
    "Nela.Durut-Azizi",
    "Jodi.Ramstack",
    "Monica.Ramirez"
)

# Enabled but former employees — disable then delete
$enabledToRemove = @(
    "alyssa.brooks",
    "ann.dery",
    "Cathy.Reece",
    "Haris.Durut",
    "Isabella.Islas",
    "Kelly.Wallace",
    "Nuria.Diaz"
)

if ($DeleteAccounts) {
    Write-Host "  Deleting disabled accounts from CN=Users..." -ForegroundColor Yellow
    foreach ($acct in $disabledToDelete) {
        try {
            # Remove from all groups first (especially Domain Admins — Monica.Ramirez!)
            $user = Get-ADUser $acct -Properties MemberOf -ErrorAction Stop
            foreach ($group in $user.MemberOf) {
                $groupName = (Get-ADGroup $group).Name
                if ($groupName -ne "Domain Users") {
                    Remove-ADGroupMember -Identity $group -Members $acct -Confirm:$false -ErrorAction SilentlyContinue
                    Write-Host "    [OK] Removed $acct from $groupName" -ForegroundColor Green
                }
            }
            Remove-ADUser -Identity $acct -Confirm:$false -ErrorAction Stop
            Write-Host "  [OK] Deleted: $acct" -ForegroundColor Green
        }
        catch {
            Write-Host "  [SKIP] $acct not found or error: $_" -ForegroundColor DarkGray
        }
    }

    Write-Host ""
    Write-Host "  Disabling + deleting former employee accounts..." -ForegroundColor Yellow
    foreach ($acct in $enabledToRemove) {
        try {
            # Disable first
            Disable-ADAccount -Identity $acct -ErrorAction SilentlyContinue
            # Remove from all groups
            $user = Get-ADUser $acct -Properties MemberOf -ErrorAction Stop
            foreach ($group in $user.MemberOf) {
                $groupName = (Get-ADGroup $group).Name
                if ($groupName -ne "Domain Users") {
                    Remove-ADGroupMember -Identity $group -Members $acct -Confirm:$false -ErrorAction SilentlyContinue
                    Write-Host "    [OK] Removed $acct from $groupName" -ForegroundColor Green
                }
            }
            Remove-ADUser -Identity $acct -Confirm:$false -ErrorAction Stop
            Write-Host "  [OK] Disabled + Deleted: $acct" -ForegroundColor Green
        }
        catch {
            Write-Host "  [SKIP] $acct not found or error: $_" -ForegroundColor DarkGray
        }
    }
} else {
    Write-Host "  [WARN] Account 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 }
}
Write-Host ""

# ============================================================
# STEP 5: Flag Lupe.Sanchez for review
# ============================================================
Write-Host "--- Step 5: Lupe.Sanchez Review ---" -ForegroundColor Yellow

try {
    $lupe = Get-ADUser -Identity "Lupe.Sanchez" -Properties Enabled, LastLogonDate, Description, DistinguishedName -ErrorAction Stop
    $guadalupe = Get-ADUser -Identity "Guadalupe.Sanchez" -Properties Enabled, LastLogonDate, Description, DistinguishedName -ErrorAction SilentlyContinue

    Write-Host "  Lupe.Sanchez:" -ForegroundColor White
    Write-Host "    DN: $($lupe.DistinguishedName)" -ForegroundColor DarkGray
    Write-Host "    Enabled: $($lupe.Enabled)" -ForegroundColor $(if ($lupe.Enabled) { "Yellow" } else { "DarkGray" })
    Write-Host "    Last Logon: $($lupe.LastLogonDate)" -ForegroundColor DarkGray
    Write-Host ""

    if ($guadalupe) {
        Write-Host "  Guadalupe.Sanchez (possible duplicate):" -ForegroundColor White
        Write-Host "    DN: $($guadalupe.DistinguishedName)" -ForegroundColor DarkGray
        Write-Host "    Enabled: $($guadalupe.Enabled)" -ForegroundColor DarkGray
        Write-Host "    Last Logon: $($guadalupe.LastLogonDate)" -ForegroundColor DarkGray
        Write-Host ""
        Write-Host "  ** REVIEW: Lupe.Sanchez may be a duplicate of Guadalupe.Sanchez (Housekeeping)." -ForegroundColor Red
        Write-Host "  ** Both accounts exist. Check with client which to keep." -ForegroundColor Red
    }
}
catch {
    Write-Host "  Lupe.Sanchez not found in AD" -ForegroundColor DarkGray
}
Write-Host ""

# ============================================================
# STEP 6: Accounts that should STAY in CN=Users
# ============================================================
Write-Host "--- Accounts staying in CN=Users (system/service) ---" -ForegroundColor Yellow
$keepInUsers = @("Administrator", "Guest", "krbtgt", "localadmin", "sysadmin", "QBDataServiceUser34")
foreach ($acct in $keepInUsers) {
    try {
        $user = Get-ADUser $acct -Properties Enabled -ErrorAction SilentlyContinue
        if ($user) {
            $status = if ($user.Enabled) { "Enabled" } else { "Disabled" }
            Write-Host "  [$status] $acct — Staying in CN=Users (system/service account)" -ForegroundColor DarkGray
        }
    }
    catch {}
}
Write-Host ""

# Accounts needing client decision
Write-Host "--- Accounts needing client decision ---" -ForegroundColor Yellow
Write-Host "  Receptionist — shared account, currently in CN=Users. Move to Departments\Resident Services?" -ForegroundColor Yellow
Write-Host "  directoryshare — shared account, currently in CN=Users. Keep as service account?" -ForegroundColor Yellow
Write-Host "  Lupe.Sanchez — see review above. Possible duplicate of Guadalupe.Sanchez." -ForegroundColor Yellow
Write-Host ""

# ============================================================
# SUMMARY: Final OU structure
# ============================================================
Write-Host "=== Final OU Structure ===" -ForegroundColor Cyan
Write-Host ""

$allOUs = Get-ADOrganizationalUnit -Filter * -Properties ProtectedFromAccidentalDeletion |
    Sort-Object DistinguishedName |
    Select-Object Name, DistinguishedName, ProtectedFromAccidentalDeletion

foreach ($ou in $allOUs) {
    # Calculate depth for indentation
    $depth = ($ou.DistinguishedName -split ',' | Where-Object { $_ -match '^OU=' }).Count - 1
    $indent = "  " * $depth
    $protected = if ($ou.ProtectedFromAccidentalDeletion) { "" } else { " [UNPROTECTED]" }
    Write-Host "  $indent$($ou.Name)$protected" -ForegroundColor White
}

Write-Host ""
Write-Host "=== OU Cleanup Complete ===" -ForegroundColor Cyan
Write-Host "Next: Run phase2-ad-setup.ps1 (security fixes, groups, computer moves)" -ForegroundColor Green
