how to have this content become body of HTML email??

$eventsDC= Get-Eventlog security -Computer $DC -InstanceId 4625 -After (Get-Date).AddDays(-7) |
   Select TimeGenerated,ReplacementStrings |
   % {
     New-Object PSObject -Property @{
      Source_Computer = $_.ReplacementStrings[13]
      UserName = $_.ReplacementStrings[5]
      IP_Address = $_.ReplacementStrings[19]
      Date = $_.TimeGenerated
    }
   }
   
$eventsDC | ConvertTo-Html -Property Source_Computer,UserName,IP_Address,Date -head $HTML -body "Generated On $Date"|
	 Out-File $Report -Append

I am working with a script that uses the above line to create an html file containing data about failed logins, then attach the html file to an email.

How can I make the $eventsDC data become text placed into the body of an HTML email??

I have the code for sending the email, using PS 1.0 net.mail.mailmessage for now, and it all works to send the above $Report file as an attachment, but I want to try to have the $Report text converted into something that can become an email body.

function FuncMail {
    #param($strTo, $strFrom, $strSubject, $strBody, $smtpServer)
    param($To, $From, $Subject, $Body, $smtpServer)
    $msg = new-object Net.Mail.MailMessage
    $smtp = new-object Net.Mail.SmtpClient($smtpServer)
    $smtp.UseDefaultCredentials = $true
    $msg.From = $From
    $msg.To.Add($To)
    $msg.Subject = $Subject
    $msg.IsBodyHtml = 1
    $msg.Body = $Report
    $msg.Attachments.Add($Report)
    $smtp.Send($msg)
    $msg.Attachments.Dispose()
}

FuncMail -To "tlyczko@mmm.org" -From "dc2@mmm.org"  -Subject "Failed Login Report" -Body "Report $Report here" -smtpServer "smtp.mmm.org"	

Suggestions anyone??

I did try using a new variable and using Out-String but this wrote the output to the view/immediate window, not into anything that could be emailed, so far as I could see…

Thank you, Tom

Or maybe there is some way I can read back out the contents of report.html into some variable that can be used as the body text??
Thank you, Tom

Yes!!! You’re on the right track with the second post. You pumped out everything to a file and then tried to pass that ‘file object’ to FuncMail and it got confused. It only sees that you passed it a file. FuncMail doesn’t know what it is or whats inside it. You say you want FuncMail to read the the files contents, interpret them as HTML code and insert them into an email???..but you don’t tell FuncMail that.

Lesson 1: Object types (Use the cmdlet Get-Member to analyze objects in more detail)

Apart from that, there were several other areas in your code that needed attention. When you call FuncMail you use a parameter -Body yet you do not use that param inside the function. You call $Report instead? FuncMail doesn’t know what $Report is because you haven’t defined it within the variable scope.

Lesson 2: Variable Scope

We could go on but it would be easier to just show you. This is how I might accomplish what you are doing.

$ComputerName = "."
$InstanceID = "4625"
$Date = Get-Date
$CutoffDate = $Date.AddDays(-100)
$To = "tlyczko@mmm.org"
$From = "dc2@mmm.org"
$Subject = "Failed Login Report"
$SMTPServer = "smtp.mmm.org"

$Events = Get-EventLog -ComputerName $ComputerName -LogName Security -InstanceId $InstanceID -After $CutoffDate | ForEach-Object {
    New-Object PSObject -Property @{
        Source_Computer = $_.ReplacementStrings[13]
        UserName = $_.ReplacementStrings[5]
        IP_Address = $_.ReplacementStrings[19]
        Date = $_.TimeGenerated
    }
}

$Body = "Reported on $Date"
$Body += "-------------------------------------------------------------------------"
$Body += $Events | ConvertTo-Html -Fragment

Send-MailMessage -To $To -From $From -Subject $Subject -Body $Body -SmtpServer $SMTPServer

Send-MailMessage is a PoSh v3 cmdlet and does the same as FuncMail. Good luck!

I was indeed attempting to reuse other code wrt FuncMail.
So I will try your suggestion for emailing…I can still use the other code to generate the report file.
I think I can figure out how to append to $Body each time it does one of the 4 servers I am evaluating.
Thank you, Tom

You might choose to write that like this.

$body = @"
Reported on $Date

"@

$email = $events | ConvertTo-Html -head $a -body “$body” | out-string

Edit: There are html breaks following the $date and $body that the forum will not display.

I tried to modify it to get events from 4 different servers, it works with 1 server, but with 4 servers, it runs forever and never sends anything:

$DCs = @('x5','x6','x7','x8')

$InstanceID = "4625"
$Date = Get-Date
$CutoffDate = $Date.AddDays(-1)
$To = "tlyczko@ms.org"
$From = "dc2@ms.org"
$Subject = "Failed Login Report"
$SMTPServer = "smtp.ms.org"

foreach ($DC in $DCs) {

$Events = Get-EventLog -ComputerName $DC -LogName Security -InstanceId $InstanceID -After $CutoffDate | ForEach-Object {
    New-Object PSObject -Property @{
        Source_Computer = $_.ReplacementStrings[13]
        UserName = $_.ReplacementStrings[5]
        #IP_Address = $_.ReplacementStrings[19]
        Date = $_.TimeGenerated
    }
}

$Body = "Reported on $Date"
# $Body += "-------------------------------------------------------------------------"
$Body += $Events | ConvertTo-Html -Fragment
}
}
# after foreach loop ends
Send-MailMessage -To $To -From $From -Subject $Subject -Body $Body -SmtpServer $SMTPServer -BodyAsHtml

What am I doing wrong with the foreach loop?? I get no feedback from PoSh.

Thank you, Tom

@Dan if you edit your reply and use

 tags the code will display better.

I tried the pre tags as well.

This has a bunch of lessthan br greaterthan’s







OIC no worries, I read it several more times and I now understand your suggestion.
Maybe someone will reply on my foreach question.
Thank you, Tom

tommls,

If you are doing a long report I find it easiest to output to htm and then attach to the message.

$events | convert-tohtml |out-file something.htm

$eventstwo | convert-tohtml |out-file something.htm -append

It’s not THAT long a report, my earlier original code does the report and attaches to a message but I am now trying to get it into an email body.
It’s maybe 50-75 lines of HTML table lines, not a lot at all.
Thank you, Tom

My point is if you have a report with multiple tables it’s easier to append to an html file then retrieve the whole html file for the body.

You can formulate the html within the body parameter but it can get messy if you have too many things going on.

$emailbody = “words html break $events htmlbreak words $eventstwo”

Based on the last code you posted you have one too many curly braces and the Send-MailMessage line has to be inside the foreach loop.

And Dan was correct I tried using HTML break tags that didn’t translate in my earlier post.

Ohhhhhhhhhhh…now I understand what you are suggesting, I would like to do that…that line with $emailbody is how I concatenate the HTML outputs of $events###??

Thank you, Tom

Thank you for feedback on curly braces though PoSh did not complain.
I wanted the body things to be concatenated so I have 4 different tables, one for each server.
I want the email sent after the four servers have been reviewed, that’s why send-mailmessage is outside the foreach loop, it’s wanted to send all four server results in one email.
Thank you, Tom

Yep, purely for visual formatting purpose in the email body only. Didn’t really have any effect on the script itself. I like to make it purdy.

note that send-mailmessage doesn’t accept anything but strings for body.

to keep it simple (can’t test this at the moment)

‘report1’,'report2 | % {

switch($_){

report1{get-process | convert-tohtml -body “reportonetitle htmlbreak”| out-file reports.htm}
report2{get-service | convert-tohtml -body “reporttwotitle htmlbreak”| out-file reports.htm -append}

}

}

$emailbody = get-content reports.htm

send-mailmessage…

Oh, now I got ya. Then you’ll need to accumulate the $Events each time the loop iterates. So change $Events = to $Events +=. You will also need to define $Events as an array before the foreach loop b/c powershell complains if you attempt to add elements to an array when it doesn’t already know the variable is an array. So above the foreach add a line $Events = @().

Ahhhhhhhhh…the missing link.
I will try all this after a looonnng meeting (ugh).
Thank you, Tom

Also, take the bits about the $Body out of the foreach loop as well and define the body right before you send the email.