Need help getting output generated in a powershell script into the body of an email

Hello Experts,

I have written a small Powershell script that pings a list of servers and shows me which ones are online and which ones are offline.  How do I get the data that the script returns into the body of an email?  Below is the script.

$Servers = @(Get-QADComputer -ManagedBy ccit | foreach{$_.name} | Sort-Object)
ForEach($Server In $Servers)
{$PingStatus = Gwmi Win32_PingStatus -Filter "Address = '$Server'" |
Select-Object StatusCode
If ($PingStatus.StatusCode -eq 0)
{Write-Host "$Server" is online and answering pings -Fore "Green"}
Else
{Write-Host "$Server" is OFFLINE and must be checked -Fore "Red"}}
LVL 1
ndalmolin_13Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

ndalmolin_13Author Commented:
Here is what I have done:
$Body = ""
$Servers = @(Get-QADComputer -ManagedBy ccit | foreach{$_.name} | Sort-Object)
ForEach($Server In $Servers){
$PingStatus = Gwmi Win32_PingStatus -Filter "Address = '$Server'" |
Select-Object StatusCode
If ($PingStatus.StatusCode -eq 0)
{$Body = "$Body$($Server) is online and answering Pings. `n"}
Else
{$Body = "$Body$($Server) is OFFLINE and must be checked. `n"}
}

This appears to give me the body of the email.  Is there a way I can make the online servers show up in green and the offline servers show up in red within the body?
ndalmolin_13Author Commented:
I'm getting closer.  Here is my script:
add-PSSnapin quest.activeroles.admanagement -ea SilentlyContinue

$Body = ""
$Servers = @(Get-QADComputer -ManagedBy ccit | foreach{$_.name} | Sort-Object)
ForEach($Server In $Servers){
$PingStatus = Gwmi Win32_PingStatus -Filter "Address = '$Server'" |
Select-Object StatusCode
If ($PingStatus.StatusCode -eq 0)
{$Body = "$Body$($Server) is online and answering pings. `n"}
Else
{$Body = "$Body$($Server) IS OFFLINE AND NEEDS TO BE CHECKED IMMEDIATELY. `n"}
}

$Mail = New-Object System.Net.Mail.MailMessage( `
  "ServerAdmin@coconino.az.gov", `
  "ndalmolin@coconino.az.gov", `
  "Server Disk Report", `
  $Body)
 
$Mail.IsBodyHTML = $True
 
$Smtp = New-Object System.Net.Mail.SmtpClient("cas-hub01.summitlan.states")
$Smtp.Send($Mail)

Here is the body of the email that I receive:
TS01 is online and answering pings. VM02 is online and answering pings. VM03 is online and answering pings. WICHITA is online and answering pings.

Here are my questions:
How can I format the body so that each server's status is on its own line?  Example:
TS01 is online and answering pings.
VM02 is online and answering pings.
VM03 is online and answering pings.
WICHITA is online and answering pings.

Can I make online servers highlighted in green and offline servers highlighted in red?

As always, any and all help is greatly appreciated.

Nick
Chris DentPowerShell DeveloperCommented:
Hi Nick,

Yes, you can.

You're writing HTML for the message body so you have to think in that. The cheapest way to modify your current code to do that is by using the deprecated <font> tag.

e.g.

$Body = "$Body<font color='green'>$($Server) is online and answering pings</font><br />`n"

$Body = "$Body<font color='red'>$($Server) IS OFFLINE AND NEEDS TO BE CHECKED IMMEDIATELY</font><br />`n"

Really we should use styles, we're not supposed to use font, but it will still work.

You may also consider that the tabular output generated by ConvertTo-Html is preferable, although you'll have to feed it an Object to make it a table (rather than lines as you have here).

You can do some pretty stuff with the output from that though. See the accepted answer for this one, the script is long and not relavant to this particular question except that it generates HTML output:

http://www.experts-exchange.com/Q_25066855.html

Ultimately, making output pretty for e-mail is far more about understanding HTML and CSS than it is about understanding PowerShell.

Chris

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Creating Active Directory Users from a Text File

If your organization has a need to mass-create AD user accounts, watch this video to see how its done without the need for scripting or other unnecessary complexities.

Chris DentPowerShell DeveloperCommented:

I forgot to mention, each on it's own line is taken care of by <br />, HTML line break.

Chris
Chris DentPowerShell DeveloperCommented:
Hell we may as well take it a few steps further :)

PowerShell 2 brought us "Test-Connection" which wraps up the WMI method you're using above and makes it easier to use and Send-MailMessage to simplify that half.

So, if I were doing this, I would consider something like this. PowerShell 2 all the way. In this version Offline servers will appear first in the list (in alphabetical order by name).

Chris
$Head = "<title>Server Status</title>
  <style type='text/css'>
    body       { font-family: sans-serif; font-size: 10pt; }
    table      { width: 100%; border-collapse: collapse; }
    th         { text-align: left; padding: 0px 5px 0px 5px; border-bottom: 1px solid #CCCCCC; }
    td         { text-align: left; padding: 0px 5px 0px 5px; color: black; }
    td.Online  { text-align: left; padding: 0px 5px 0px 5px; color: green; }
    td.Offline { text-align: left; padding: 0px 5px 0px 5px; color: red; font-weight: bold; }
  </style>"

$ServerStatus = Get-QADComputer -ManagedBy ccit | 
  Select-Object Name,
   @{n='Status';e={ If (Test-Connection $($_.Name) -Quiet) { "Online" } Else { "Offline" } }} |
  Sort-Object Status, Name

$HtmlServerStatus = [String]($ServerStatus | ConvertTo-Html -Head $Head)
$HtmlServerStatus = $HtmlServerStatus -Replace "<td>Online", "<td class='Online'>Online"
$HtmlServerStatus = $HtmlServerStatus -Replace "<td>Offline", "<td class='Offline'>Offline"

Send-MailMessage -To "you@yourdomain.com" -Subject "Server Status" -From "admin@yourdomain.com" `
  -Body $HtmlServerStatus -SmtpServer "SomeServer" -BodyAsHtml

Open in new window

ndalmolin_13Author Commented:
Outstanding!!  This worked great.  It looks like I'm going to have to teach myself HTML as well as powershell.  Can you recommend any online resources for either?
Chris DentPowerShell DeveloperCommented:

For HTML and CSS it's difficult to find anywhere better than here:

http://www.w3schools.com/

You don't need much to make things pretty, and it's useful as a reference as well.

Chris
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.