Powershell – Exchange Environmental Check

Powershell – Exchange Environmental Check

I have adapted the ‚ÄúModern Exchange Environment Check‚ÄĚ from¬†Satheshwaran Manoharan¬†and for use on a Exchange Server 2016 environment.
Added to the already excelent script is the following

  • Section Headers
  • MailboxDB provisioning Status
  • Whitespace check
  • Exchange Log Dir Size
  • Exchange Server Drive Space
  • Mail Queue Checks
  • House Keeping of created files


I feel that this is now a more complete report of the Exchange Server environment and the servers it runs upon.

I had toyed with adding the ‚Äú10 largest user Mailboxes‚ÄĚ to the account, but this takes a considerable time to run and would be better suited to ad-hoc reporting.

[CC lang=’powershell’]
# Requires -version 2 – Runs in Exchange Management Shell

# It displays Complete Exchange Environment Information in a modern HTML. It covers only Exchange 2010 or later.

# Set Working Dir
Push-Location (Split-Path -path $MyInvocation.MyCommand.Definition -Parent)

#Add Exchange Server snapin if not already loaded

if (!(Get-PSSnapin | where {$_.Name -eq “Microsoft.Exchange.Management.PowerShell.E2010”}))
{
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction SilentlyContinue
}
Write-Progress¬†-Activity¬†“Date”¬†-status¬†“Collecting Dates info”
$Date = Get-date -ErrorAction SilentlyContinue

# —– Settings —-

#Should the Script Open the HTML File locally on Finishing the script – Say Yes – if you wish to

$Openhtmllocally¬†=¬†“No”

Write-Progress¬†-Activity¬†“Email Settings”¬†-status¬†“Storing Email Settings”
## —– Email —-Fill in with your details

$EmailTo¬†=¬†“[email protected]
$EmailFrom¬†=¬†“[email protected]
$EmailSubject¬†=¬†“Exchange Status Report $Date”
$SmtpServer¬†=¬†“mail.yourdomain.com”
$Date¬†= (Get-Date¬†-format¬†“dd-MM-yyyy”)
$Attachment¬†=¬†“.\output\ModernExchangeEnvironmentReport($date).htm”

# —– Settings —-

#Collecting Environment Information
Write-Progress¬†-Activity¬†“Exchange Servers”¬†-status¬†“Collecting Exchange Servers info”
$ExchangeServers = Get-ExchangeServer -ErrorAction SilentlyContinue

Write-Progress¬†-Activity¬†“Mailboxes”¬†-status¬†“Collecting Collecting Mailboxes info”
$mailboxes = Get-mailbox -ResultSize Unlimited -ErrorAction SilentlyContinue

Write-Progress¬†-Activity¬†“Databases”¬†-status¬†“Collecting Databases info”
$Databases = Get-mailboxdatabase -Status -ErrorAction SilentlyContinue

Write-Progress¬†-Activity¬†“DAG”¬†-status¬†“Collecting DAG info”
$DAGS = Get-DatabaseAvailabilityGroup -ErrorAction SilentlyContinue

Write-Progress¬†-Activity¬†“DistributionGroups”¬†-status¬†“Collecting DistributionGroup info”
$DistributionGroups = Get-DistributionGroup -ResultSize Unlimited -ErrorAction SilentlyContinue

Write-Progress¬†-Activity¬†“DynamicDistributionGroups”¬†-status¬†“Collecting DynamicDistributionGroup info”
$DynamicGroups = Get-DynamicDistributionGroup -ResultSize Unlimited -ErrorAction SilentlyContinue

Write-Progress¬†-Activity¬†“MailContacts”¬†-status¬†“Collecting MailContacts info”
$MailContacts = Get-MailContact -ResultSize Unlimited -ErrorAction SilentlyContinue

Write-Progress¬†-Activity¬†“Public Folder”¬†-status¬†“Collecting Public Folder Mailboxes info”
$PFmailboxes = Get-mailbox -PublicFolder -ResultSize Unlimited -ErrorAction SilentlyContinue

Write-Progress¬†-Activity¬†“SendConnectors”¬†-status¬†“Collecting SendConnectors info”
$SendConnectors = Get-SendConnector -ErrorAction SilentlyContinue

Write-Progress¬†-Activity¬†“Accepted Domains”¬†-status¬†“Collecting Accepted Domains info”
$AcceptedDomains = Get-AcceptedDomain -ErrorAction SilentlyContinue

Write-Progress¬†-Activity¬†“OrgAdmins”¬†-status¬†“Collecting OrgAdmins info”
$OrgAdmins¬†=¬†Get-RoleGroupMember¬†“Organization Management”¬†-ErrorAction¬†SilentlyContinue

#Applying Initial CSS For the HTML
Write-Progress¬†-Activity¬†“ModernExchangeEnvironmentReport”¬†-status¬†“Applying CSS”
$head¬†=¬†@”
Volume Report

“@

#Create Tables in split so that users can remove or add tables easily.
$start¬†=¬†@”

“@
Write-Progress¬†-Activity¬†“ModernExchangeEnvironmentReport”¬†-status¬†“Writing Enviroment Initial Info”
$Table1¬†=@”

Exchange Environment Report

No.Exchange Servers No.Databases No.Mailboxes No.PublicFolder Mailboxes No.DistributionGroups No.DynamicGroups No.Contacts No.DAG No.Domains No.OrgAdmins Date
$($ExchangeServers.count) $($Databases.count) $($mailboxes.count) $($PFmailboxes.count) $($DistributionGroups.count) $($DynamicGroups.count) $($MailContacts.count) $($DAG.count) $($AcceptedDomains.count) $($OrgAdmins.count) $($Date)

“@

Write-Progress¬†-Activity¬†“ExchangeServers”¬†-status¬†“Writing ExchangeServers info”
$Table2 =
foreach ($server in ($ExchangeServers))
{“

“}

$table2close¬†=¬†@”

Exchange Servers Roles Edition Site Version Operating System SendConnectors Used
$($server.name) $($server.serverrole) $($server.edition) $($server.site.name) $($server.AdmindisplayVersion -replace “version”,”) $($windows2012above = ((Get-WmiObject -ComputerName $server.name -class Win32_OperatingSystem -ErrorAction SilentlyContinue) | Where-Object{($_.Version -like “6.*”) -or ($_.version -like “10.*”) -and ($_.Version -notlike “6.1.*”) -and ($_.version -notlike “6.0.*”)}).version.count
if ($windows2012above -eq 1)
{(Get-CimInstance -ComputerName $server.name Win32_OperatingSystem).caption -replace “Microsoft Windows Server”,”})
$(($SendConnectors | Where-Object{$_.SourceTransportServers -match “$($server.name)”}).identity.name)

“@

Write-Progress¬†-Activity¬†“Databases”¬†-status¬†“Writing Database info”
$Table3¬†=@”

Mailbox DB Stats

“@

$Table3data = foreach ($Database in $Databases)
{
$dbsize¬†= $($Database.databasesize¬†-replace¬†“\(.*”,”)

$dbWhitespace¬†= $($database.AvailableNewMailboxSpace¬†-replace¬†“\(.*”,”)

$Mountstatus = $($Database.Mounted)

if($Mountstatus¬†-eq¬†“True”)
{
$Mcolor¬†=¬†“#99FF66”
}
else
{
$Mcolor¬†=¬†“#FF5050”
}

$ContentIndexStatus¬†= $((Get-MailboxDatabaseCopyStatus¬†“$($database.name)\$($database.servername)”).contentindexstate)
if($ContentIndexStatus¬†-eq¬†“Healthy”)
{
$color¬†=¬†“#99FF66”
}
else
{
$color¬†=¬†“#FF5050”
}


}

$table3close¬†=¬†@”

Mailbox Databases Mounted ContentIndex DBSize WhiteSpace Mailboxes Master Group Database copies MbxRetention.Days ItemRetention.Days CircularLogging Provisioning Suspended Provisioning Disabled Last Full Backup
$($Database.name) $($Database.Mountedonserver) $ContentIndexStatus $dbsize $dbWhitespace $((get-mailbox -database $Database).count) $($Database.MasterServerOrAvailabilityGroup) $($Database.databasecopies.identity.name) $($Database.MailboxRetention.days) $($Database.DeletedItemRetention.days) $($Database.CircularLoggingEnabled -replace “False”,”No” -replace “True”,”Yes”) $($database.IsSuspendedFromProvisioning -replace “False”,”No” -replace “True”,”Yes”) $($database.IsExcludedFromProvisioning -replace “False”,”No” -replace “True”,”Yes”) $($database.lastfullbackup)

“@

if($dags.count -ge 1)
{
Write-Progress¬†-Activity¬†“Dag”¬†-status¬†“Writing DaG info”
$Table4¬†=@”

DAG statistics

“@

$Table4data = foreach ($dag in $dags)
{“


}

$table4close¬†=¬†@”

DAG Name Member Servers DAC Mode Witness server Witness Directory
$($DAG.name) $($dag.servers.name) $($dag.DatacenterActivationMode) $($dag.Witnessserver) $($dag.WitnessDirectory)

“@

Write-Progress¬†-Activity¬†“Dag”¬†-status¬†“Writing DaG Replication info”
$Table5¬†=@”

Server Statistics

“@

Write-Progress¬†-Activity¬†“Dag”¬†-status¬†“Writing DaG info”

$Table5data = foreach ($dag in $dags)
{
foreach ($member in $((Get-DatabaseAvailabilityGroup $dag).servers.name))
{
$replstatus = Test-ReplicationHealth $member
for($i=0;$i -lt $replstatus.count;$i++)
{
if($replstatus.result[$i].value¬†-eq¬†“Passed”)
{
$Rcolor¬†=¬†“#99FF66”
}
else
{
$Rcolor¬†=¬†“#FF5050”
}


}
}
}

$table5close¬†=¬†@”

Server Check Result Error
$(($replstatus).Server[$i]) $(($replstatus).Check[$i]) $($replstatus.Result[$i].value) $(($replstatus).Error[$i])

“@
}
else
{
Write-Progress¬†-Activity¬†“Dag”¬†-status¬†“Skipping DaG – No DAG Found”
}

$MailqueueTb=¬†@”

Mail Queues

“@

Write-Progress¬†-Activity¬†“Mail Queues”¬†-status¬†“Perusing the Mail Queues”

Foreach ($server in $ExchangeServers){
$MailQueues¬†+=¬†Get-Queue¬†-server¬†$server¬†|¬†Select-Object¬†NextHopDomain, Status, @{Label=”Message Count”;Expression={if¬†($_.MessageCount¬†-lt¬†30){“#div_gre”+¬†$_.MessageCount}else{“#div_red”+¬†$_.MessageCount}}}, Identity
}
$MailQueues = $MailQueues|ConvertTo-Html -Fragment
$file¬†=¬†“.\MailQueues.txt”
$MailQueues | SC $file
(GC $file|Select-Object -Skip 3)|SC $file
$MailQueues = GC $file
$MailQueues¬†=¬†$MailQueues¬†-replace¬†‘

Next Hop Domain Status Message Count Freespace (GB)
#div_red’,¬†‘


$MailQueues¬†=¬†$MailQueues¬†-replace¬†‘

#div_gre’,¬†‘


Remove-Item $file

$table6=¬†@”

Server Drive Space Statistics

“@

Write-Progress¬†-Activity¬†“Drive Space”¬†-status¬†“Writing Drive Space info”
$threshold=’90’
Write-Verbose¬†-Message¬†“===================================`n= DISK SPACE CHECKS =`n= Checks the size of volumes, including =`n= mount points, and shows those with =`n= less than $threshold% free. =`n============================================”
$thresholdMsg¬†=¬†“

Drive(s) listed below have less than $threshold% free space. Drives above this threshold will not be listed.


$onlinelist = @()
$offlinelist = @()
$results = @()
Write-Verbose¬†-Message¬†‘Performing ping test on servers …’
$exchangeservers|ForEach-Object -Process {
if(Test-Connection -ComputerName $_ -Quiet -Count 2)
{
Write-Verbose¬†-Message¬†“`t$_ is up”
$onlinelist += $_
}
else
{
Write-Warning¬†-Message¬†“`t`t`t`t$_ is down”
$offlinelist += $_
}
}

if($offlinelist -ne $null)
{
$ofs¬†=¬†‘,’
$offlineMsg¬†=¬†“

The following servers are offline: $offlinelist


$ofs¬†=¬†‘ ‘
}
ForEach($server in $onlinelist)
{
Try
{
Write-Verbose¬†-Message¬†“Gathering drive info on $server”
$row = Get-WmiObject -ComputerName $server -Class Win32_Volume `
|
Where-Object -FilterScript {
$_.DriveType¬†-eq¬†‘3’
} `
|
Where-Object -FilterScript {
$_.Capacity -gt 0
} `
|
Where-Object -FilterScript {
($_.freespace/$_.capacity)*100 -lt $threshold
} `
|
Select-Object -Property SystemName, Name, @{
n =¬†‘Capacity (GB)’
e = {
‘{0:n2}’¬†-f¬†($_.capacity/1gb)
}
}, @{
n =¬†‘FreeSpace (GB)’
e = {
‘{0:n2}’¬†-f¬†($_.freeSpace/1gb)
}
}, @{
n =¬†‘PercentFree’
e = {
if(‘{0:n2}’¬†-f¬†(($_.freespace/$_.capacity)*100)¬†-lt¬†10)
{
“#div_red”+'{0:n2}’¬†-f¬†($_.freespace/$_.capacity*100)
}
elseif(‘{0:n2}’¬†-f¬†(($_.freespace/$_.capacity)*100)¬†-lt¬†15)
{
“#div_ora”+'{0:n2}’¬†-f¬†($_.freespace/$_.capacity*100)
}
elseif(‘{0:n2}’¬†-f¬†(($_.freespace/$_.capacity)*100)¬†-lt¬†20)
{
“#div_yel”+'{0:n2}’¬†-f¬†(($_.freespace/$_.capacity)*100)
}
elseif(‘{0:n2}’¬†-f¬†($_.freespace/$_.capacity*100)¬†-gt¬†20)
{
“#div_gre”+'{0:n2}’¬†-f¬†(($_.freespace/$_.capacity)*100)
}
}
}
}
Catch [System.Exception]
{
Write-Warning -Message $_.Exception.Message
}
$results += $row
}
$results = $results|ConvertTo-Html -Fragment
$file¬†=¬†“.\results.txt”
$results | SC $file
(GC $file|Select-Object -Skip 3)|SC $file
$results = GC $file
$results¬†=¬†$results¬†-replace¬†‘

Server Volume Capacity (GB) Freespace (GB) Percent Free
#div_yel’,¬†‘


$results¬†=¬†$results¬†-replace¬†‘

#div_ora’,¬†‘


$results¬†=¬†$results¬†-replace¬†‘

#div_red’,¬†‘


$results¬†=¬†$results¬†-replace¬†‘

#div_gre’,¬†‘


Remove-Item $file

$table6close=@”

“@

Write-Progress¬†-Activity¬†“Log Sizes”¬†-status¬†“Writing Log Size info”
$table7=@”

Exchange Log Sizes

“@

$trupath = @()
$databases | ForEach-ObJect{
$logpath = $_.LogFolderPath.ToString()
$logserver = $_.Servername.ToString()
$trupath¬†+=¬†$logpath¬†-replace¬†“C:\\”,¬†“\\$logserver\c$\”
}

$table7data=ForEach($pat in $trupath){
$size¬†=¬†“{0:N2} MB”¬†-f¬†((GCI¬†$pat¬†-recurse¬†|Measure-Object¬†-Property¬†Length¬†-Sum¬†-ErrorAction¬†Stop).Sum / 1MB)


}

$table7close=@”

Log Path Size MB
$Pat $size

“@

$complete¬†=¬†@”


“@

#Combining All Tables.

$alltables¬†=¬†“$start $Table1 $Table2 $table2close $Table3 $Table3data $table3close $Table4 $Table4data $table4close $Table5 $Table5data $table5close $mailqueuetb $mailqueues $table6 $table6close $results $Table7 $Table7data $table7close ”

$Combine = ConvertTo-Html -Head $head -Body $alltables

#Saving HTML File To the local C Drive – You can modify as per your wish.
$html += $Combine
$html > $Attachment

#open the HTML File Locally
If($Openhtmllocally¬†-eq¬†“yes”)
{
Invoke-Item¬†“$Attachment”
}
else
{
Write-Progress¬†-Activity¬†“Open HTML”¬†-status¬†“Settings – Do not Open”
}
#Sending Email Message

#Send-mailmessage¬†-to¬†$EmailTo¬†-from¬†$EmailFrom¬†-subject¬†$EmailSubject¬†-SmtpServer¬†$SmtpServer¬†-Body¬†“Please see attached”¬†-BodyAsHtml¬†-Attachments¬†$Attachment¬†-ErrorAction¬†SilentlyContinue

# House Keping
GCI .\output\ | Where-Object -FilterScript {
$_.LastWriteTime -lt (Get-Date).AddDays(-6)}|Remove-Item
[/CC]

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to Top