Private/_New-MigrationAssessmentHtml.ps1

function _New-MigrationAssessmentHtml {
    param(
        [hashtable]$Assessment
    )

    $css = @"
    <style>
        body { font-family: Segoe UI, Arial, sans-serif; margin: 20px; background: #f5f5f5; }
        h1 { color: #2c3e50; border-bottom: 3px solid #8e44ad; padding-bottom: 10px; }
        h2 { color: #34495e; margin-top: 30px; border-bottom: 1px solid #bdc3c7; padding-bottom: 5px; }
        .meta { color: #7f8c8d; margin-bottom: 20px; }
        .dashboard { display: flex; gap: 15px; flex-wrap: wrap; margin-bottom: 20px; }
        .card { background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); min-width: 180px; text-align: center; }
        .card .number { font-size: 36px; font-weight: bold; color: #8e44ad; }
        .card .label { color: #7f8c8d; font-size: 12px; margin-top: 5px; }
        .card.warning .number { color: #e67e22; }
        table { border-collapse: collapse; width: 100%; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,0.1); margin-bottom: 20px; }
        th { background: #8e44ad; color: #fff; padding: 10px 8px; text-align: left; font-size: 11px; }
        td { padding: 8px; border-bottom: 1px solid #ecf0f1; font-size: 11px; }
        tr:nth-child(even) { background: #f9f9f9; }
        tr:hover { background: #f0e6f6; }
        .large { background: #fdebd0 !important; }
        .hold { color: #e74c3c; font-weight: bold; }
        .note { background: #fff3cd; padding: 15px; border-radius: 5px; border-left: 4px solid #8e44ad; margin: 10px 0; }
    </style>
"@


    $mbx = $Assessment['Mailboxes']
    $totalMbx = $mbx.Count
    $totalSizeGB = [math]::Round(($mbx | Measure-Object -Property SizeGB -Sum).Sum, 1)
    $avgSizeGB = if ($totalMbx -gt 0) { [math]::Round($totalSizeGB / $totalMbx, 2) } else { 0 }
    $largeMbx = @($mbx | Where-Object SizeGB -gt 50).Count
    $holdMbx = @($mbx | Where-Object { $_.LitigationHold -or $_.RetentionHold }).Count
    $sharedMbx = @($mbx | Where-Object RecipientType -eq 'SharedMailbox').Count
    $dgCount = $Assessment['DistGroups'].Count
    $ruleCount = $Assessment['MailFlowRules'].Count
    $pfCount = if ($Assessment['PublicFolders']) { $Assessment['PublicFolders'].Count } else { 0 }

    # Top 20 largest mailboxes
    $mbxRows = ($mbx | Sort-Object SizeGB -Descending | Select-Object -First 20 | ForEach-Object {
        $rowClass = if ($_.SizeGB -gt 50) { " class='large'" } else { '' }
        $holdFlag = if ($_.LitigationHold -or $_.RetentionHold) { "<span class='hold'> [HOLD]</span>" } else { '' }
        "<tr$rowClass><td>$($_.DisplayName)$holdFlag</td><td>$($_.PrimarySmtpAddress)</td><td>$($_.RecipientType)</td><td>$($_.SizeGB) GB</td><td>$($_.ItemCount)</td><td>$($_.HasArchive)</td><td>$($_.Database)</td></tr>"
    }) -join "`n"

    # Distribution group rows
    $dgRows = ($Assessment['DistGroups'] | ForEach-Object {
        "<tr><td>$($_.Name)</td><td>$($_.GroupType)</td><td>$($_.MemberCount)</td><td>$($_.NestedGroups)</td><td>$($_.ExternalMembers)</td><td>$($_.MigrationNotes)</td></tr>"
    }) -join "`n"

    # Rule rows
    $ruleRows = ($Assessment['MailFlowRules'] | ForEach-Object {
        "<tr><td>$($_.Name)</td><td>$($_.Priority)</td><td>$($_.State)</td><td>$($_.MigrationConcerns)</td></tr>"
    }) -join "`n"

    @"
<!DOCTYPE html>
<html>
<head><title>Exchange Migration Assessment</title>$css</head>
<body>
    <h1>Exchange Migration Pre-Assessment</h1>
    <div class="meta">Generated: $(Get-Date -Format 'yyyy-MM-dd HH:mm')</div>
 
    <div class="dashboard">
        <div class="card"><div class="number">$totalMbx</div><div class="label">Total Mailboxes</div></div>
        <div class="card"><div class="number">$totalSizeGB GB</div><div class="label">Total Data</div></div>
        <div class="card"><div class="number">$avgSizeGB GB</div><div class="label">Avg Mailbox Size</div></div>
        <div class="card $(if($largeMbx -gt 0){'warning'})"><div class="number">$largeMbx</div><div class="label">Mailboxes > 50 GB</div></div>
        <div class="card $(if($holdMbx -gt 0){'warning'})"><div class="number">$holdMbx</div><div class="label">On Legal Hold</div></div>
        <div class="card"><div class="number">$sharedMbx</div><div class="label">Shared Mailboxes</div></div>
    </div>
 
    <div class="note">
        <strong>Estimated Migration Data:</strong> $totalSizeGB GB across $totalMbx mailboxes.
        $(if($largeMbx -gt 0){"<br><strong>Note:</strong> $largeMbx mailbox(es) exceed 50 GB and may require special handling."})
        $(if($holdMbx -gt 0){"<br><strong>Note:</strong> $holdMbx mailbox(es) on legal hold - coordinate with legal before migration."})
    </div>
 
    <h2>Top 20 Largest Mailboxes</h2>
    <table>
        <tr><th>Name</th><th>Email</th><th>Type</th><th>Size</th><th>Items</th><th>Archive</th><th>Database</th></tr>
        $mbxRows
    </table>
 
    <h2>Distribution Groups ($dgCount)</h2>
    <table>
        <tr><th>Name</th><th>Type</th><th>Members</th><th>Nested</th><th>External</th><th>Migration Notes</th></tr>
        $dgRows
    </table>
 
    <h2>Mail Flow Rules ($ruleCount)</h2>
    <table>
        <tr><th>Rule</th><th>Priority</th><th>State</th><th>Migration Concerns</th></tr>
        $ruleRows
    </table>
 
    $(if($pfCount -gt 0){
    "<h2>Public Folders ($pfCount)</h2>
    <div class='note'>Public folder migration requires separate planning. See CSV export for full details.</div>"
    })
</body>
</html>
"@

}