Skip to content
This repository was archived by the owner on Sep 17, 2023. It is now read-only.

Commit cbc6f60

Browse files
committed
Bug fixes and enhancements
CCS fixes for Html header tags (issue #5) New script parameter ShowDriveNames added to optionally show drive names for EDB/LOG file paths in database table (issue #4) Exchange organization name added to report header close #4 close #5
1 parent 00446f4 commit cbc6f60

File tree

3 files changed

+115
-45
lines changed

3 files changed

+115
-45
lines changed

EnvironmentReport.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,14 @@ h2 {
1111
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
1212
font-size: 14px;
1313
}
14+
h3 {
15+
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
16+
font-size: 12px;
17+
}
18+
h4 {
19+
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
20+
font-size: 10px;
21+
}
1422

1523
/* Header, first table row showing labels for totals */
1624
table.header {

Get-ExchangeEnvironmentReport.ps1

Lines changed: 86 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE
88
RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.
99
10-
Version 2.1 2019-09-26
10+
Version 2.2 January 2020
1111
1212
Based on the original 1.6.2 version by Steve Goodman
1313
@@ -65,10 +65,6 @@
6565
6666
IMPORTANT NOTE: The script requires WMI and Remote Registry access to Exchange servers from the server
6767
it is run from to determine OS version, Update Rollup, Exchange 2007/2003 cluster and DB size information.
68-
69-
Updates
70-
- 2.1 Table header label updated for a more consistent labeling
71-
- 2.0 Initial Release
7268
7369
.LINK
7470
http://scripts.granikos.eu
@@ -94,6 +90,9 @@
9490
.PARAMETER ServerFilter
9591
Use a text based string to filter Exchange Servers by, e.g., NL-*
9692
Note the use of the wildcard (*) character to allow for multiple matches.
93+
94+
.PARAMETER ShowDriveNames
95+
Include drive names of EDB file path and LOG file folder in database report table
9796
9897
.EXAMPLE
9998
Generate the HTML report
@@ -102,7 +101,10 @@
102101
.EXAMPLE
103102
Generate am HTML report and send the result as HTML email with attachment to the specified recipient using a dedicated smart host
104103
.\Get-ExchangeEnvironmentReport.ps1 -HTMReport ExchangeEnvironment.html -SendMail -ViewEntireForet $true -MailFrom roaster@mcsmemail.de -MailTo grillmaster@mcsmemail.de -MailServer relay.mcsmemail.de
105-
104+
105+
.EXAMPLE
106+
Generate the HTML report including EDB and LOG drive names
107+
.\Get-ExchangeEnvironmentReport.ps1 -ShowDriveNames -HTMLReport .\report.html
106108
#>
107109
[CmdletBinding()]
108110
param(
@@ -112,13 +114,16 @@ param(
112114
[string]$MailTo = '',
113115
[string]$MailServer = '',
114116
[bool]$ViewEntireForest=$true,
115-
[string]$ServerFilter='*'
117+
[string]$ServerFilter='*',
118+
[switch]$ShowDriveNames
116119
)
117120

118121
# Warning Limits, adjust as needed
119122
$MinFreeDiskspace = 10 # Mark free space less than this value (%) in red
120123
$MaxDatabaseSize = 250 # Mark database larger than this value (GB) in red
121124

125+
# Default variables
126+
$NotAvailable = 'N/A'
122127

123128
# Sub-Function to Get Database Information. Shorter than expected..
124129
function Get-DatabaseAvailabilityGroupInformation {
@@ -148,6 +153,23 @@ function Get-DatabaseInformation {
148153
# Circular Logging, Last Full Backup
149154
if ($Database.CircularLoggingEnabled) { $CircularLoggingEnabled='Yes' } else { $CircularLoggingEnabled = 'No' }
150155
if ($Database.LastFullBackup) { $LastFullBackup=$Database.LastFullBackup.ToString() } else { $LastFullBackup = 'Not Available' }
156+
157+
# Drive Letter, GitHub issue #4
158+
$DriveNameEdb = ''
159+
try {
160+
$DriveNameEdb = $Database.EdbFilePath.DriveName
161+
}
162+
catch {
163+
$DriveNameEdb = $NotAvailable
164+
}
165+
166+
$DriveNameLog = ''
167+
try {
168+
$DriveNameLog = $Database.LogFolderPath.DriveName
169+
}
170+
catch {
171+
$DriveNameLog = $NotAvailable
172+
}
151173

152174
# Mailbox Average Sizes
153175
$MailboxStatistics = [array]($ExchangeEnvironment.Servers[$Database.Server.Name].MailboxStatistics | Where-Object {$_.Database -eq $Database.Identity})
@@ -258,6 +280,8 @@ function Get-DatabaseInformation {
258280
CopyCount = $CopyCount
259281
FreeLogDiskSpace = $FreeLogDiskSpace
260282
FreeDatabaseDiskSpace = $FreeDatabaseDiskSpace
283+
DriveNameEdb = $DriveNameEdb
284+
DriveNameLog = $DriveNameLog
261285
}
262286
}
263287

@@ -304,7 +328,6 @@ function Get-ExchangeServerInformation {
304328
$MaxPrefDatabases = 0
305329
$MaxActiveDatabases = 0
306330
$NotSet = '--'
307-
$NotAvailable = 'N/A'
308331

309332
# Get WMI Information: Operatin System
310333
$tWMI = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $ExchangeServer.Name -ErrorAction SilentlyContinue
@@ -377,7 +400,7 @@ function Get-ExchangeServerInformation {
377400
}
378401

379402
if($ExchangeMajorVersion -ge 14) {
380-
$mailboxServer = Get-MailboxServer $($ExchangeServer.Name)
403+
$mailboxServer = Get-MailboxServer -Identity $($ExchangeServer.Name)
381404

382405
# 2019-05-20 TST Gather max active/max preferred database config
383406
if($ExchangeMajorVersion -lt 15) {
@@ -755,7 +778,7 @@ function Get-HtmlOverview {
755778
$AlternateRow=0
756779

757780
foreach ($Server in $Servers.Value) {
758-
$Output+="<tr"
781+
$Output+='<tr'
759782

760783
if ($AlternateRow) {
761784
$Output+=" class='alternaterow'"
@@ -774,25 +797,25 @@ function Get-HtmlOverview {
774797
$Output+="</td><td>$($ExVersionStrings["$($Server.ExchangeMajorVersion).$($Server.ExchangeSPLevel)"].Long)"
775798

776799
if ($Server.RollupLevel -gt 0) {
777-
$Output+=" UR$($Server.RollupLevel)"
800+
$Output+=(' UR{0}' -f $Server.RollupLevel)
778801
if ($Server.RollupVersion) {
779-
$Output+=" $($Server.RollupVersion)"
802+
$Output+=(' {0}' -f $Server.RollupVersion)
780803
}
781804
}
782805

783-
$Output+="</td>"
806+
$Output+='</td>'
784807

785808
$ExchangeEnvironment.TotalServersByRole.GetEnumerator() | Sort-Object -Property Name | ForEach-Object{
786-
$Output+="<td"
809+
$Output+='<td'
787810
if ($Server.Roles -contains $_.Key) {
788811
$Output+=" class='roledata'>"
789812
}
790813
else {
791-
$Output+=" />"
814+
$Output+=' />'
792815
}
793816

794817
if (($_.Key -eq 'ClusteredMailbox' -or $_.Key -eq 'Mailbox' -or $_.Key -eq 'BE') -and $Server.Roles -contains $_.Key) {
795-
$Output+="$($Server.Mailboxes)</td>"
818+
$Output+=('{0}</td>' -f $Server.Mailboxes)
796819
}
797820
}
798821

@@ -801,7 +824,7 @@ function Get-HtmlOverview {
801824
$Output+="<td align=""center"">$($Server.MaximumPreferredDatabases) / $($Server.MaximumActiveDatabases)</td><td>$($Server.OSVersion)</td><td>$($Server.OSServicePack)</td></tr>"
802825
}
803826
else {
804-
$Output+="<td align=""center"">Not Applicable</td><td>$($Server.OSVersion)</td><td>$($Server.OSServicePack)</td></tr>"
827+
$Output+=('<td align=""center"">Not Applicable</td><td>{0}</td><td>{1}</td></tr>' -f $Server.OSVersion, $Server.OSServicePack)
805828
}
806829

807830
# $Output+="<td>$($Server.OSVersion)</td><td>$($Server.OSServicePack)</td></tr>";
@@ -821,14 +844,13 @@ function Get-HtmlDatabaseInformationTable {
821844
)
822845

823846
# Only Show Archive Mailbox Columns, Backup Columns and Circ Logging if at least one DB has an Archive mailbox, backed up or Cir Log enabled.
824-
$ShowArchiveDBs=$False
825-
$ShowLastFullBackup=$False
826-
$ShowCircularLogging=$False
827-
$ShowStorageGroups=$False
828-
$ShowCopies=$False
829-
$ShowFreeDatabaseSpace=$False
830-
$ShowFreeLogDiskSpace=$False
831-
847+
$ShowArchiveDBs = $False
848+
$ShowLastFullBackup = $False
849+
$ShowCircularLogging = $False
850+
$ShowStorageGroups = $False
851+
$ShowCopies = $False
852+
$ShowFreeDatabaseSpace = $False
853+
$ShowFreeLogDiskSpace = $False
832854

833855
foreach ($Database in $Databases) {
834856
if ($Database.ArchiveMailboxCount -gt 0) {
@@ -854,17 +876,19 @@ function Get-HtmlDatabaseInformationTable {
854876
}
855877
}
856878

857-
$Output="<table class='databases'>
858-
<tr class='databases'>
859-
<th>Server</th>"
879+
$Output="<table class='databases'>"
880+
881+
#region database table header
882+
$Output +="<tr class='databases'>
883+
<th>Server</th>"
860884

861885
if ($ShowStorageGroups) {
862-
$Output+="<th>Storage Group</th>"
886+
$Output+='<th>Storage Group</th>'
863887
}
864888

865-
$Output+="<th>Database Name</th>
889+
$Output+='<th>Database Name</th>
866890
<th>Standard Mailboxes</th>
867-
<th>Av. Mailbox Size</th>"
891+
<th>Av. Mailbox Size</th>'
868892

869893
if ($ShowArchiveDBs) {
870894
$Output+='<th>Archive Mailboxes</th><th>Av. Archive Size</th>'
@@ -887,12 +911,19 @@ function Get-HtmlDatabaseInformationTable {
887911
if ($ShowCopies) {
888912
$Output+='<th>DB Copies (n)</th>'
889913
}
914+
915+
# Drive names, issue #4
916+
if($ShowDriveNames) {
917+
$Output+='<th>EDB / LOG</th>'
918+
}
890919

891920
$Output+='</tr>'
921+
#endregion
922+
892923
$AlternateRow=0
893924

894925
foreach ($Database in $Databases) {
895-
$Output+="<tr"
926+
$Output+='<tr'
896927

897928
if ($AlternateRow) {
898929
$Output+=" class='alternaterow'"
@@ -954,17 +985,24 @@ function Get-HtmlDatabaseInformationTable {
954985
if ($ShowCopies) {
955986
$Output+="<td>$($Database.Copies | ForEach-Object{$_}) ($($Database.CopyCount))</td>"
956987
}
988+
989+
# Drive names, issue #4
990+
if ($ShowDriveNames) {
991+
$Output+="<td class='center'>$("{0} / {1}" -f $Database.DriveNameEdb, $Database.DriveNameLog)</td>"
992+
}
957993
$Output+='</tr>'
958994
}
959995

960996
$Output+='</table><br />'
961997

962-
$Output+=("<p class='dagtablefooter'>Maximum mailbox database size: {0} GB<br/>Minumum free disk space: {1}%</p>" -f $MaxDatabaseSize, $MinFreeDiskspace)
998+
$Output += '<p class="dagtablefooter">Explanation</p>'
999+
$Output += ("<p class='dagtablefooter'>Maximum mailbox database size: {0} GB<br/>Minimum free disk space: {1}%</p>" -f $MaxDatabaseSize, $MinFreeDiskspace)
9631000

9641001
$Output
9651002
}
9661003

9671004
function Get-HtmlReportHeader {
1005+
[CmdletBinding()]
9681006
param(
9691007
$ExchangeEnvironment,
9701008
$Path
@@ -979,23 +1017,20 @@ function Get-HtmlReportHeader {
9791017
$UseCss = $true
9801018

9811019
# Header
982-
$Output="
1020+
$Output='
9831021
<html>
9841022
<body>
985-
<title>Exchange Environment Report</title>"
1023+
<title>Exchange Environment Report</title>'
9861024

9871025
if($UseCss -and (Test-Path -Path (Join-Path -Path (Split-Path -Parent $Path) -ChildPath $CssFileName))) {
9881026
$Output += "<style type=""text/css"">$(Get-Content -Path (Join-Path -Path (Split-Path -Parent $Path) -ChildPath $CssFileName))</style>"
9891027
}
9901028

991-
992-
$Output += ("<font size=""1"" face=""Segoe UI,Arial,sans-serif"">
993-
<h2 align=""center"">Exchange Environment Report</h3>
994-
<h4 align=""center"">Generated {0}</h5>
995-
</font>
1029+
$Output += ("<h2 align=""center"">Exchange Environment Report</h2><h3 align=""center"">Organization: {3}</h3>
1030+
<h4 align=""center"">Generated {0}</h4>
9961031
<table class='header'>
9971032
<tr class='header'>
998-
<th colspan=""{1}"" class='header'>{2}</th>" -f (Get-Date -Format $DateLabelFormat), $ExchangeEnvironment.TotalMailboxesByVersion.Count, $LabelTotalServers)
1033+
<th colspan=""{1}"" class='header'>{2}</th>" -f (Get-Date -Format $DateLabelFormat), $ExchangeEnvironment.TotalMailboxesByVersion.Count, $LabelTotalServers, $ExchangeEnvironment.OrganizationName)
9991034

10001035
if ($ExchangeEnvironment.RemoteMailboxes) {
10011036
$Output+=("<th colspan=""{0}"" class='header'>{1}</th>" -f ($ExchangeEnvironment.TotalMailboxesByVersion.Count+2), $LabelTotalMailboxes)
@@ -1036,12 +1071,13 @@ function Get-HtmlReportHeader {
10361071
$ExchangeEnvironment.TotalServersByRole.GetEnumerator()|Sort-Object -Property Name| ForEach-Object{$Output+="<td class='headerdata'>$($_.Value)</td>"}
10371072

10381073
#$Output+="</tr><tr><tr></table><br>"
1039-
$Output += "</tr></table><!-- End --><br />"
1074+
$Output += '</tr></table><!-- End --><br />'
10401075

10411076
$Output
10421077
}
10431078

10441079
function Get-HtmlDagHeader {
1080+
[CmdletBinding()]
10451081
param (
10461082
$DAG
10471083
)
@@ -1055,7 +1091,7 @@ function Get-HtmlDagHeader {
10551091

10561092
$DAG.Members | ForEach-Object { $Output+=('{0} ' -f $_) }
10571093

1058-
$Output += "</td></tr></table><br />"
1094+
$Output += '</td></tr></table><br />'
10591095

10601096
$Output
10611097
}
@@ -1157,6 +1193,7 @@ $ExchangeEnvironment = @{
11571193
Servers = @{}
11581194
DAGs = @()
11591195
NonDAGDatabases = @()
1196+
OrganizationName = ''
11601197
}
11611198

11621199
# 1.5.7 Exchange Major Version String Mapping
@@ -1265,6 +1302,10 @@ else {
12651302
# 2.3 Populate Information we know
12661303
$ExchangeEnvironment.Add('TotalMailboxes',$Mailboxes.Count + $ExchangeEnvironment.RemoteMailboxes)
12671304

1305+
# 2.4 Organizational Info
1306+
1307+
$ExchangeEnvironment.OrganizationName = (Get-OrganizationConfig).Name
1308+
12681309
# 3 Process High-Level Exchange Information
12691310

12701311
# 3.1 Collect Exchange Server Information
@@ -1367,8 +1408,8 @@ if ($ExchangeEnvironment.NonDAGDatabases.Count) {
13671408

13681409
Show-ProgressBar -PercentComplete 80 -Status 'Writing HTML Non-DAG Database Information' -Stage 4
13691410

1370-
$Output+="<table class=""dagsummary"">
1371-
<tr class=""dagsummarynondag""><th>Mailbox Databases (Non-DAG)</th></table>"
1411+
$Output+='<table class="dagsummary">
1412+
<tr class="dagsummarynondag"><th>Mailbox Databases (Non-DAG)</th></table>'
13721413

13731414
# Get Table HTML for non-DAG databases
13741415
$Output+=Get-HtmlDatabaseInformationTable -Databases $ExchangeEnvironment.NonDAGDatabases

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,15 @@ The PowerShell script does not gather information on public folders or analyzes
5757
* Exchange Server Management Shell 2010 or newer
5858
* WMI and Remote Registry access from the computer running the script to all internal Exchange Servers
5959

60+
## Release
61+
62+
* 2.0 : Initial Community Release of the updated original script
63+
* 2.1 : Table header label updated for a more consistent labeling
64+
* 2.2 : Bug fixes and enhancements
65+
* CCS fixes for Html header tags (issue #5)
66+
* New script parameter _ShowDriveNames_ added to optionally show drive names for EDB/LOG file paths in database table (issue #4)
67+
* Exchange organization name added to report header
68+
6069
## Example Report
6170

6271
![Example Report](/images/screenshot.png)
@@ -92,6 +101,10 @@ By default, true. Set the option in Exchange 2007 or 2010 to view all Exchange s
92101
Use a text based string to filter Exchange Servers by, e.g., NL-*
93102
Note the use of the wildcard (*) character to allow for multiple matches.
94103

104+
### ShowDriveNames
105+
106+
Include drive names of EDB file path and LOG file folder in database report table
107+
95108
## Examples
96109

97110
### Example 1
@@ -110,6 +123,14 @@ Generate an HTML report and save the report as 'report.html'
110123
.\Get-ExchangeEnvironmentReport.ps1 -HTMLReport .\report.html
111124
```
112125

126+
### Example 3
127+
128+
Generate the HTML report including EDB and LOG drive names
129+
130+
``` PowerShell
131+
.\Get-ExchangeEnvironmentReport.ps1 -ShowDriveNames -HTMLReport .\report.html
132+
```
133+
113134
## Note
114135

115136
THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE

0 commit comments

Comments
 (0)