
close
close
Chance to win $250 in Petri 2023 Audience Survey
In the comments on a recent article about creating a color coded report of domain controller service statuses, there was a question in the comments about sending the same type of information, presumably colorized, in an email message. PowerShell makes it very easy to send email with the Send-MailMessage cmdlet. You can even send HTML messages, which is the key to answering this question.
As in the previous articles, I need to get the service information from my domain controllers. Of course, this could be other data that you want to report.
$dcs = "chi-dc01","chi-dc02","chi-dc04" $svcs = "adws","dns","kdc","netlogon" $data = Get-Service -name $svcs -ComputerName $dcs
I’ll also define a title for the report.
$ReportTitle = "Domain Controller Services"
Now for the first tricky part. When we create HTML documents in PowerShell, typically with ConvertTo-HTML, style is applied separately, usually through a CSS file. But you can also embed style information in the head of an HTML document. I’ll create a here-string with an embedded style sheet.
$head = @" <Title>$ReportTitle</Title> <style> body { background-color:#FFFFFF; font-family:Tahoma; font-size:12pt; } td, th { border:1px solid black; border-collapse:collapse; } th { color:white; background-color:black; } table, tr, td, th { padding: 2px; margin: 0px } table { width:95%;margin-left:5px; margin-bottom:20px;} .stopped {color: Red } .running {color: Green } .pending {color: #DF01D7 } .paused {color: #FF8000 } .other {color: Black } </style> <br> <H1>$ReportTitle</H1> "@
The relevant parts for dynamically colorizing our output is in lines 13 to 17. These settings will be used to define a new style class. The settings inside the curly brackets will be applied for each match. All I’m doing is setting the font color. I’m using a mix of color names like red and HTML color codes. The better practice would probably be to use color codes for everything. Now we’re ready to start generating some HTML.
I only need a few properties, so I’ll select them and pipe to Convertto-Html. I don’t want a complete document yet, because I’m going to have to adjust it first to account for the different service statues. I have found the easiest solution is to create an HTML fragment, but treat it as an XML document.
[xml]$html = $data | Select @{Name="DomainController";Expression={$_.MachineName.ToUpper()}},Name,Displayname,Status | ConvertTo-Html -Fragment
Why? Because I can now “walk” the document.
HTML as an XML document (Image Credit: Jeff HIcks)
1..($html.table.tr.count-1) | foreach { #enumerate each TD $html.table.tr[$_] }
Enumerating the table (Image Credit: Jeff Hicks)
1..($html.table.tr.count-1) | foreach { #enumerate each TD $td = $html.table.tr[$_] $td.childnodes }
Expanding the table rows (Image Credit: Jeff Hicks)
1..($html.table.tr.count-1) | foreach { #enumerate each TD $td = $html.table.tr[$_] $td.childnodes.item(3) }
Listing text values (Image Credit: Jeff HIcks)
1..($html.table.tr.count-1) | foreach { #enumerate each TD $td = $html.table.tr[$_] #create a new class attribute $class = $html.CreateAttribute("class") #set the class value based on the item value Switch ($td.childnodes.item(3).'#text') { "Running" { $class.value = "running"} "Stopped" { $class.value = "stopped"} "Pending" { $class.value = "pending"} "paused" { $class.value = "paused"} Default { $class.value = "other"} } #append the class $td.childnodes.item(3).attributes.append($class) | Out-Null }
If I look again, I’ll now see the class attribute.
The new class attribute (Image Credit: Jeff Hicks)
The updated HTML code (Image Credit: Jeff Hicks)
Sample HTML report (Image Credit: Jeff HIcks)
[string]$body = ConvertTo-HTML -Head $head -Body $html.InnerXml -PostContent "<h6>Created $(Get-Date)</h6>"
The body needs to be a string, which is why I am explicitly telling PowerShell to treat it as a string. I can define a hashtable of parameter values for Send-MailMessage.
$mailParams=@{ To = "jeff@mycompany.com" From = "jeff@mycompany.com" Subject = "Domain Controller Status Report" SMTPServer = "smtp.mycompany.com" Body = $Body BodyAsHTML = $True Port = 587 UseSSL = $True Credential = $mailCred }
You will have different needs depending on your mail server. I splat the parameters:
Send-MailMessage @mailparams
And the mail is sent.
Sample HTML email (Image Credit: Jeff Hicks)
More in PowerShell
Most popular on petri