try { # Import admin credentials $serverAddress = Get-Content -Path ".\DefaultServer.txt" $credential = Import-Clixml -Path .\AdminCredential.xml # Establish session with Exchange Server Write-Host "Connecting to Exchange server $serverAddress..." $session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "http://$serverAddress/PowerShell/" -Authentication Kerberos -Credential $credential Import-PSSession $session -DisableNameChecking -WarningAction SilentlyContinue -ErrorAction Stop Write-Host "Successfully connected." # Define output file path in the user's Downloads folder $outputFile = "$env:USERPROFILE\Downloads\ExchangeDatabaseMailboxListReport(Navitas).html" # --- Data Collection Variables --- $totalUserMailboxes = 0 $totalSharedMailboxes = 0 $databaseStats = @() # Array to hold stats for the column chart # Array to hold detailed info for sorting and report generation $allDatabaseDetails = @() # --- HTML Report Setup --- # Define CSS styles and include Chart.js library via CDN # MODIFIED: Added fixed table layout and column width definitions $head = @" "@ # --- Collect Data from All Databases First --- Write-Host "Retrieving database information..." $databases = Get-MailboxDatabase -Status | Select-Object Name, DatabaseSize Write-Host "Found $($databases.Count) databases. Processing mailbox data..." foreach ($db in $databases) { $dbName = $db.Name Write-Host " Processing database: $dbName" $dbSize = $db.DatabaseSize -replace '\s*\(.*\)', '' # Clean up size string # Retrieve mailboxes under the database and exclude "Discovery Search Mailbox" $mailboxes = Get-Mailbox -Database $dbName | Where-Object {$_.DisplayName -ne "Discovery Search Mailbox"} | Select-Object DisplayName, PrimarySmtpAddress, RecipientTypeDetails # Separate user mailboxes and shared mailboxes $userMailboxes = $mailboxes | Where-Object {$_.RecipientTypeDetails -eq "UserMailbox"} | Sort-Object DisplayName | Select-Object DisplayName, PrimarySmtpAddress $sharedMailboxes = $mailboxes | Where-Object {$_.RecipientTypeDetails -eq "SharedMailbox"} | Sort-Object DisplayName | Select-Object DisplayName, PrimarySmtpAddress # Get Counts for this DB $currentUserCount = $userMailboxes.Count $currentSharedCount = $sharedMailboxes.Count # Corrected simple assignment # Accumulate Totals (for Pie Chart) $totalUserMailboxes += $currentUserCount $totalSharedMailboxes += $currentSharedCount # Store stats for Column Chart $databaseStats += [PSCustomObject]@{ DatabaseName = $dbName UserCount = $currentUserCount SharedCount = $currentSharedCount } # Store detailed info for report generation and sorting $allDatabaseDetails += [PSCustomObject]@{ Name = $dbName Size = $dbSize UserMailboxes = $userMailboxes # Store the actual collection SharedMailboxes = $sharedMailboxes # Store the actual collection UserCount = $currentUserCount SharedCount = $currentSharedCount HasMailboxes = ($currentUserCount + $currentSharedCount) -gt 0 } Write-Host " Found $currentUserCount user mailboxes, $currentSharedCount shared mailboxes." } # End foreach database data collection # --- Start Building HTML Body --- $bodyContent = "

Exchange Database Mailbox Report

" $bodyContent += "

Generated on: $(Get-Date)

" $bodyContent += "

Note: System mailboxes such as 'Discovery Search Mailbox' have been excluded from this report.

" # --- Generate HTML for Databases WITH Mailboxes --- $databasesWithMailboxes = $allDatabaseDetails | Where-Object { $_.HasMailboxes } | Sort-Object Name if ($databasesWithMailboxes) { Write-Host "Generating report section for databases with mailboxes..." $bodyContent += "

Databases with Mailboxes

" # Distinct separator foreach ($dbInfo in $databasesWithMailboxes) { $bodyContent += "

Database: $($dbInfo.Name)

" $bodyContent += "

Total Size: $($dbInfo.Size)

" # Add User Mailboxes Table $bodyContent += "

User Mailboxes

" if ($dbInfo.UserMailboxes) { $bodyContent += $dbInfo.UserMailboxes | ConvertTo-Html -As Table -Fragment -PreContent "

Count: $($dbInfo.UserCount)

" } else { $bodyContent += "

No user mailboxes found in this database.

" } # Add Shared Mailboxes Table $bodyContent += "

Shared Mailboxes

" if ($dbInfo.SharedMailboxes) { $bodyContent += $dbInfo.SharedMailboxes | ConvertTo-Html -As Table -Fragment -PreContent "

Count: $($dbInfo.SharedCount)

" } else { $bodyContent += "

No shared mailboxes found in this database.

" } } } else { Write-Host "No databases found with user or shared mailboxes." $bodyContent += "

Databases with Mailboxes

" $bodyContent += "

No databases found containing user or shared mailboxes (excluding system mailboxes).

" } # --- Generate HTML for Databases WITHOUT Mailboxes --- $databasesWithoutMailboxes = $allDatabaseDetails | Where-Object { -not $_.HasMailboxes } | Sort-Object Name if ($databasesWithoutMailboxes) { Write-Host "Generating report section for databases without mailboxes..." $bodyContent += "

Databases without Mailboxes

" # Distinct separator foreach ($dbInfo in $databasesWithoutMailboxes) { $bodyContent += "

Database: $($dbInfo.Name)

" $bodyContent += "

Total Size: $($dbInfo.Size)

" $bodyContent += "

No user or shared mailboxes found in this database.

" # Simplified message } } else { Write-Host "All databases have mailboxes or no empty databases were found." } # --- Add Summary Chart Placeholders and Script --- $bodyContent += "
" $bodyContent += "

Mailbox Count Summary Charts

" $bodyContent += "

These charts summarize mailbox counts across ALL databases included in this report.

" # Clarifying note # Start the charts wrapper div $bodyContent += "
" # Chart 1: Pie Chart Container (Overall Totals) $bodyContent += "
" $bodyContent += "

Total Mailbox Distribution (All Databases)

" # Clarified title $bodyContent += "" $bodyContent += "
" # Chart 2: Column Chart Container (Per Database Comparison) $bodyContent += "
" $bodyContent += "

Mailbox Counts per Database

" $bodyContent += "" $bodyContent += "
" # End the charts wrapper div $bodyContent += "
" # --- Prepare Data for JavaScript --- # Sort databaseStats by name to match the column chart labels with potential report sorting $databaseStats = $databaseStats | Sort-Object DatabaseName $dbLabels = $databaseStats.DatabaseName | ForEach-Object { "'$_'" } $jsDbLabels = "[$($dbLabels -join ', ')]" $jsUserCounts = "[$($databaseStats.UserCount -join ', ')]" $jsSharedCounts = "[$($databaseStats.SharedCount -join ', ')]" # --- Embed JavaScript for Chart Generation --- # (JavaScript code is unchanged as it correctly generates summary charts) $chartScript = @" "@ # Append the chart script to the body content $bodyContent += $chartScript # --- Finalize and Save HTML Report --- Write-Host "Generating HTML report with reordered sections, summary charts, and fixed table columns..." ConvertTo-Html -Head $head -Body $bodyContent -Title "Exchange Database Mailbox Report" | Out-File $outputFile -Encoding UTF8 Write-Host "Report saved to $outputFile" -ForegroundColor Green # Optional: Automatically open the report Invoke-Item -Path $outputFile # Clean up session Write-Host "Removing PSSession..." Remove-PSSession $session Write-Host "Script finished." } catch { Write-Host "An error occurred:" -ForegroundColor Red Write-Host $_.Exception.Message -ForegroundColor Red # Optional: More detailed error info # Write-Host $_.ScriptStackTrace Write-Host "Script failed." if ($PSBoundParameters.ContainsKey('session') -and $session -ne $null -and (Get-PSSession | Where-Object {$_.ID -eq $session.ID})) { Write-Host "Attempting to remove PSSession after error..." Remove-PSSession $session } }