Get-IISSmtpState.ps1
<#PSScriptInfo .VERSION 2.0 .GUID 35b14c0b-4e9a-4111-9d9a-cfe6cf038219 .AUTHOR June Castillote .COPYRIGHT june.castillote@gmail.com .TAGS .LICENSEURI .PROJECTURI https://github.com/junecastillote/Get-IISSMTPState .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES .PRIVATEDATA #> <# .DESCRIPTION IIS SMTP Server Status Report #> param ( [cmdletbinding()] # list of IIS SMTP Servers, accepts array. [Parameter(Mandatory=$true,Position=0)] [string[]] $computerName, #path to the report directory (eg. c:\scripts\report) [Parameter(Mandatory=$true,Position=1)] [string] $reportDirectory, #Threshold for Queue [Parameter()] [int] $queueThreshold, #Threshold for Pickup [Parameter()] [int] $pickupThreshold, #Threshold for Drop [Parameter()] [int] $dropThreshold, #Threshold for BadMail [Parameter()] [int] $badMailThreshold, #path to the log directory (eg. c:\scripts\logs) [Parameter()] [string] $logDirectory, #prefix string for the report (ex. COMPANY) [Parameter()] [string] $orgName, #Switch to enable email report [Parameter()] [ValidateSet("ErrorOnly","Always")] [string] $sendEmail, #Sender Email Address [Parameter()] [string] $From, #Recipient Email Addresses - separate with comma [Parameter()] [string[]] $To, #smtpServer [Parameter()] [string] $smtpServer, #Port [Parameter()] [int] $Port, #switch to indicate whether SMTP Authentication is required [Parameter()] [switch] $smtpAuthRequired, #credential for SMTP server (if applicable) [Parameter()] [pscredential] $smtpCredential, #switch to indicate if SSL will be used for SMTP relay [Parameter()] [switch] $useSSL ) [string]$today = Get-Date -Format F #................................... #Region CSS #................................... $css_string = @' <style type="text/css"> #HeadingInfo { font-family:"Consolas"; width:100%; border-collapse:collapse; } #HeadingInfo td, #HeadingInfo th { font-size:0.8em; padding:3px 7px 2px 7px; } #HeadingInfo th { font-size:2.0em; font-weight:normal; text-align:left; padding-top:5px; padding-bottom:4px; background-color:#604767; color:#fff; } #SectionLabels { font-family:"Calibri"; width:100%; border-collapse:collapse; } #SectionLabels th.data { font-size:2.0em; text-align:left; padding-top:5px; padding-bottom:4px; background-color:#fff; color:#000; } #data { font-family:"Calibri"; width:100%; border-collapse:collapse; } #data td, #data th { font-size:0.8em; border:1px solid #DDD; padding:3px 7px 2px 7px; } #data th { font-size:0.8em; padding-top:5px; padding-bottom:4px; background-color:#00B388; color:#fff; text-align:left; } #data td { font-size:0.8em; padding-top:5px; padding-bottom:4px; text-align:left; } #data td.bad { font-size:0.8em; font-weight: bold; padding-top:5px; padding-bottom:4px; color:#f04953; } #data td.good { font-size:0.8em; font-weight: bold; padding-top:5px; padding-bottom:4px; color:#01a982; } .status { width: 10px; height: 10px; margin-right: 7px; margin-bottom: 0px; background-color: #CCC; background-position: center; opacity: 0.8; display: inline-block; } .green { background: #01a982; } .purple { background: #604767; } .orange { background: #ffd144; } .red { background: #f04953; } </style> '@ #................................... #Region CSS #................................... #................................... #Region FUNCTIONS #................................... Function Stop-TxnLogging { $txnLog="" Do { try { Stop-Transcript | Out-Null } catch [System.InvalidOperationException]{ $txnLog="stopped" } } While ($txnLog -ne "stopped") } #Function to Start Transaction Logging Function Start-TxnLogging { param ( [Parameter(Mandatory=$true,Position=0)] [string]$logDirectory ) Stop-TxnLogging Start-Transcript $logDirectory -Append } #Function to get Script Version and ProjectURI for PSv4 Function Get-ScriptInfo { param ( [Parameter(Mandatory=$true,Position=0)] [string]$Path ) $props = @{ Version = (Select-String -Pattern ".VERSION" -Path $Path)[0].ToString().split(" ")[1] ProjectURI = (Select-String -Pattern ".PROJECTURI" -Path $Path)[0].ToString().split(" ")[1] } $scriptInfo = New-Object PSObject -Property $props Return $scriptInfo } #................................... #EndRegion #................................... Stop-TxnLogging Clear-Host #Get Script Information if ($PSVersionTable.PSVersion.Major -lt 5) { $scriptInfo = Get-ScriptInfo -Path $MyInvocation.MyCommand.Definition } else { $scriptInfo = Test-ScriptFileInfo -Path $MyInvocation.MyCommand.Definition } #................................... #Region PARAMETER CHECK #................................... $isAllGood = $true if ($sendEmail) { if (!$From) { Write-Host (get-date -Format "dd-MMM-yyyy hh:mm:ss tt") ": ERROR: A valid sender email address is not specified." -ForegroundColor Yellow $isAllGood = $false } if (!$To) { Write-Host (get-date -Format "dd-MMM-yyyy hh:mm:ss tt") ": ERROR: No recipients specified." -ForegroundColor Yellow $isAllGood = $false } if (!$smtpServer ) { Write-Host (get-date -Format "dd-MMM-yyyy hh:mm:ss tt") ": ERROR: No SMTP Server specified." -ForegroundColor Yellow $isAllGood = $false } if (!$Port ) { Write-Host (get-date -Format "dd-MMM-yyyy hh:mm:ss tt") ": ERROR: No SMTP Port specified." -ForegroundColor Yellow $isAllGood = $false } if ($smtpAuthRequired) { if (!$smtpCredential) { Write-Host (get-date -Format "dd-MMM-yyyy hh:mm:ss tt") ": ERROR: SMTP Server requires authentication, but no credential was specified. Please specify using the -smtpCredential parameter." -ForegroundColor Yellow $isAllGood = $false } } } if ($isAllGood -eq $false) { Write-Host (get-date -Format "dd-MMM-yyyy hh:mm:ss tt") ": ERROR: Exiting Script." -ForegroundColor Yellow EXIT } #................................... #EndRegion PARAMETER CHECK #................................... #................................... #Region PATHS #................................... $logFile = $logDirectory +"\Log_$((get-date).tostring("yyyy_MMM_dd")).log" $outputHTMLFile = $reportDirectory +"\IIS_SMTPServer_Report_$((get-date).tostring("yyyy_MMM_dd")).html" #Create folders if not found if ($logDirectory) { if (!(Test-Path $logDirectory)) { New-Item -ItemType Directory -Path $logDirectory | Out-Null #start transcribing Start-TxnLogging $logFile } else { Start-TxnLogging $logFile } } if (!(Test-Path $reportDirectory)) { New-Item -ItemType Directory -Path $reportDirectory | Out-Null } #................................... #EndRegion PATHS #................................... #................................... #Region COLLECT IIS SMTP SERVER DETAILS #................................... $serverCollection = @() foreach ($computer in $computerName) { Write-host (Get-Date -Format "dd-MMM-yyyy hh:mm:ss tt") ": Processing $($computer)" -ForegroundColor Yellow $temp = "" | Select-Object Computer,QueueDirectory,PickupDirectory,BadMailDirectory,DropDirectory,Service,QueueCount,PickupCount,BadMailCount,DropCount,QueueSize,PickupSize,BadMailSize,DropSize,QueueStatus,PickupStatus,BadMailStatus,DropStatus,ServiceStatus,ServerStatus,CheckItems #NOTE: This script will only check the instance smtpsvc/1 - which is the default smtp virtual server $n = Get-WmiObject -ComputerName $computer -Namespace "root\MicrosoftIISV2" -Class IISSMTPSERVERSETTING -ErrorAction SilentlyContinue -ErrorVariable wmiErr | Where-Object {$_.name -eq 'smtpsvc/1'} $svcStatus = Get-Service -ComputerName $computer -Name SMTPSVC -ErrorAction SilentlyContinue -ErrorVariable svcErr $temp.Computer = $computer #all status start off as PASSED $temp.ServerStatus = "Passed" $temp.QueueStatus = "Passed" $temp.PickupStatus = "Passed" $temp.BadMailStatus = "Passed" $temp.DropStatus = "Passed" $temp.ServiceStatus = "Passed" $temp.CheckItems = @() #computer Status if (!$wmiErr) { $temp.QueueDirectory = "\\$($computer)\" + ($n.QueueDirectory -replace ":","$") $temp.PickupDirectory = "\\$($computer)\" + ($n.PickupDirectory -replace ":","$") $temp.BadMailDirectory = "\\$($computer)\" + ($n.BadMailDirectory -replace ":","$") $temp.DropDirectory = "\\$($computer)\" + ($n.DropDirectory -replace ":","$") $queue = Get-ChildItem $temp.QueueDirectory -ErrorAction SilentlyContinue -ErrorVariable queueVar | Measure-Object -property length -sum $pickup = Get-ChildItem $temp.PickupDirectory -ErrorAction SilentlyContinue -ErrorVariable pickupVar | Measure-Object -property length -sum $badmail = Get-ChildItem $temp.BadMailDirectory -ErrorAction SilentlyContinue -ErrorVariable badmailVar | Measure-Object -property length -sum $drop = Get-ChildItem $temp.DropDirectory -ErrorAction SilentlyContinue -ErrorVariable dropVar | Measure-Object -property length -sum #error checks if ($queueVar) { $temp.CheckItems += $queueVar.Exception.Message $temp.QueueDirectory = $queueVar.Exception.Message $temp.QueueCount = 0 $temp.QueueSize = 0 } else { $temp.QueueCount = $queue.count $temp.QueueSize = ($queue.sum) / 1KB } if ($pickupVar) { $temp.CheckItems += $pickupVar.Exception.Message $temp.PickupDirectory = $pickupVar.Exception.Message $temp.pickupCount = 0 $temp.pickupSize = 0 } else { $temp.pickupCount = $pickup.count $temp.pickupSize = ($pickup.sum) / 1KB } if ($badmailVar) { $temp.CheckItems += $badmailVar.Exception.Message $temp.BadMailDirectory = $badmailVar.Exception.Message $temp.badmailCount = 0 $temp.badmailSize = 0 } else { $temp.badmailCount = $badMail.count $temp.badmailSize = ($badMail.sum) / 1KB } if ($dropVar) { $temp.CheckItems += $dropVar.Exception.Message $temp.DropDirectory = $dropVar.Exception.Message $temp.DropCount = "0" $temp.dropSize = 0 } else { $temp.DropCount = $drop.count $temp.dropSize = ($drop.sum) / 1KB } #queue threshold tripped if ($queueThreshold -and ($queue.Count) -gt $queueThreshold) { $temp.QueueStatus = "Failed" $temp.ServerStatus = "Failed" $temp.CheckItems += "Queue Count is $($queue.Count) which is over the theshold of $($queueThreshold)" } #pickup threshold tripped if ($pickupThreshold -and ($pickup.count) -gt $pickupThreshold) { $temp.PickupStatus = "Failed" $temp.ServerStatus = "Failed" $temp.CheckItems += "Pickup Count is $($pickup.Count) which is over the theshold of $($pickupThreshold)" } #badmail threshold tripped if ($badMailThreshold -and ($badmail.count) -gt $badMailThreshold) { $temp.BadMailStatus = "Failed" $temp.ServerStatus = "Failed" $temp.CheckItems += "BadMail Count is $($badmail.Count) which is over the theshold of $($badMailThreshold)" } #drop threshold tripped if ($dropThreshold -and ($drop.Count) -gt $dropThreshold) { $temp.DropStatus = "Failed" $temp.ServerStatus = "Failed" $temp.CheckItems += "Drop Count is $($drop.Count) which is over the theshold of $($dropThreshold)" } } else { $temp.QueueDirectory = $wmiErr.Exception.Message $temp.PickupDirectory = $wmiErr.Exception.Message $temp.BadMailDirectory = $wmiErr.Exception.Message $temp.DropDirectory = $wmiErr.Exception.Message $temp.QueueStatus = "Failed" $temp.PickupStatus = "Failed" $temp.BadMailStatus = "Failed" $temp.DropStatus = "Failed" $temp.ServerStatus = "Failed" $temp.QueueCount = 0 $temp.QueueSize = 0 $temp.PickupCount = 0 $temp.PickupSize = 0 $temp.BadMailCount = 0 $temp.BadMailSize = 0 $temp.DropCount = 0 $temp.DropSize = 0 $temp.CheckItems += ("WMI Error: " +$wmiErr.Exception.Message) } #Service Status if (!$svcErr) { $temp.Service = $svcStatus.Status if ($temp.Service -ne 'Running') { $temp.ServiceStatus = "Failed" $temp.ServerStatus = "Failed" $temp.CheckItems += "SMTP Service is not in 'Running' state" } } else { $temp.Service = $svcErr.Exception.Message $temp.ServiceStatus = "Failed" $temp.ServerStatus = "Failed" $temp.CheckItems += ("Service Error: " + $svcErr.Exception.Message) } $serverCollection += $temp } $serverCollection #................................... #EndRegion COLLECT IIS SMTP SERVER DETAILS #................................... #................................... #Region WRITE REPORT #................................... $failedServerCount = ($serverCollection | Where-Object {$_.ServerStatus -eq 'Failed'}).count $mailSubject = "IIS SMTP Service Report | $($today)" if ($orgName) { if ($failedServerCount -gt 1) { $mailSubject = "ALERT!!! - [$($orgName)] | IIS SMTP Service Report | $($today)" } else { $mailSubject = "[$($orgName)] | IIS SMTP Service Report | $($today)" } } $htmlBody = "<html><head><title>" if ($orgName) { $header = "[$($orgName)]<br />IIS SMTP Service Report<br />$($today)" } else { $header = "IIS SMTP Service Report<br />$($today)" } $htmlBody += "</title><meta http-equiv=""Content-Type"" content=""text/html; charset=ISO-8859-1"" />" $htmlBody += $css_string $htmlBody += '</head><body>' $htmlBody += '<table id="HeadingInfo">' $htmlBody += '<tr><th>'+$header+'</th></tr>' $htmlBody += '</table><hr />' $htmlBody += '<table id="SectionLabels">' $htmlBody += '<tr><th class="data">----Issues Summary----</th></tr></table>' $htmlBody += '<table id="data"><tr><th>Check Item</th><th>Details</th></tr>' foreach ($s in ($serverCollection | Where-Object {$_.ServerStatus -eq 'Failed'})) { $htmlBody += '<tr><td>' + $s.Computer + '</td><td><ol type="1"><li>'+ ($s.CheckItems -join "</li><li>")+'</li></ol></td>' } $htmlBody += '</table><hr />' $htmlBody += '<table id="SectionLabels">' $htmlBody += '<tr><th class="data">----Server Details----</th></tr></table>' $htmlBody += '<table id="data">' $htmlBody += '<tr><th>Computer</th><th>Service</th><th>Queue [Count/Size (KB)]</th><th>Pickup [Count/Size (KB)]</th><th>BadMail [Count/Size (KB)]</th><th>Drop [Count/Size (KB)]</th></tr>' foreach ($s in $serverCollection) { $htmlBody += '<tr><td>'+$s.Computer+'</td>' if ($s.ServiceStatus -eq 'Passed') { $htmlBody += '<td class="good">'+ $s.ServiceStatus + '</td>' } else { $htmlBody += '<td class="bad">'+ $s.ServiceStatus + '</td>' } if ($s.QueueStatus -eq 'Passed') { $htmlBody += '<td class="good">'+$s.QueueCount+'/'+$s.QueueSize+'</td>' } else { $htmlBody += '<td class="bad">Failed</td>' } if ($s.PickupStatus -eq 'Passed') { $htmlBody += '<td class="good">'+$s.PickupCount+'/'+$s.PickupSize+'</td>' } else { $htmlBody += '<td class="bad">Failed</td>' } if ($s.BadMailStatus -eq 'Passed') { $htmlBody += '<td class="good">'+$s.BadMailCount+'/'+$s.BadMailSize+'</td>' } else { $htmlBody += '<td class="bad">Failed</td>' } if ($s.DropStatus -eq 'Passed') { $htmlBody += '<td class="good">'+$s.DropCount+'/'+$s.DropSize+'</td>' } else { $htmlBody += '<td class="bad">Failed</td>' } } $htmlBody += '</table><hr />' #$htmlBody += '<table id="SectionLabels">' #$htmlBody += '<tr><th class = "data">----END of REPORT----</th></tr></table><hr />' $htmlBody += '<p><font size="2" face="Consolas"><b><center>----END of REPORT----</center></b><br />' $htmlBody += '<p><font size="2" face="Consolas"><u>Report Paremeters</u><br />' $htmlBody += '<b>[THRESHOLD]</b><br />' $htmlBody += 'Queue: ' + $queueThreshold + '<br />' $htmlBody += 'Pickup: ' + $pickupThreshold + '<br />' $htmlBody += 'BadMail: ' + $badMailThreshold + '<br />' $htmlBody += 'Drop: ' + $dropThreshold + '<br />' $htmlBody += '<br /><b>[MAIL]</b><br />' $htmlBody += 'SMTP Server: ' + $smtpServer + '<br />' $htmlBody += 'Port: ' + $Port + '<br />' $htmlBody += 'SSL: ' + $useSSL + '<br />' $htmlBody += 'Authentication: ' + $smtpAuthRequired + '<br />' $htmlBody += '<br /><b>[REPORT]</b><br />' $htmlBody += "Generated from Server: $($env:COMPUTERNAME)<br />" $htmlBody += 'Script Path: ' + $MyInvocation.MyCommand.Definition $htmlBody += '<p>' $htmlBody += '<a href="'+ $scriptInfo.ProjectURI +'">IIS Smtp State '+ $scriptInfo.Version +'</a>' $htmlBody += '</body></html>' $htmlBody | Out-File $outputHTMLFile Write-host (Get-Date -Format "dd-MMM-yyyy hh:mm:ss tt") ": Report saved in $($outputHTMLFile)" -ForegroundColor Yellow #................................... #EndRegion WRITE REPORT #................................... #................................... #Region SEND REPORT #................................... if ($sendEmail) { [string]$mailBody = Get-Content $outputHTMLFile -Raw $mailParams = @{ From = $From To = $To smtpServer = $smtpServer Port = $Port useSSL = $useSSL body = $mailBody bodyashtml = $true subject = $mailSubject } if ($failedServerCount -gt 1) { $mailParams += @{priority = "HIGH"} } else { $mailParams += @{priority = "LOW"} } if ($smtpAuthRequired) { $mailParams += @{credential = $smtpCredential} } #Always if ($sendEmail -eq 'Always') { Write-Host (get-date -Format "dd-MMM-yyyy hh:mm:ss tt") ": Sending email to" ($To -join ", ") -ForegroundColor Yellow Send-MailMessage @mailParams } #ErrorOnly AND failedServerCount if ($sendEmail -eq 'ErrorOnly' -and $failedServerCount -gt 1) { Write-Host (get-date -Format "dd-MMM-yyyy hh:mm:ss tt") ": Sending email to" ($To -join ", ") -ForegroundColor Yellow Send-MailMessage @mailParams } } #................................... #EndRegion SEND REPORT #................................... Stop-TxnLogging |