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

This topic contains 21 replies, has 3 voices, and was last updated by Profile photo of tommls tommls 6 months, 1 week ago.

  • Author
    Posts
  • #41301
    Profile photo of tommls
    tommls
    Participant
    $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

    • This topic was modified 6 months, 1 week ago by Profile photo of tommls tommls.
  • #41327
    Profile photo of tommls
    tommls
    Participant

    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

  • #41329
    Profile photo of Jack Neff
    Jack Neff
    Participant

    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!

  • #41331
    Profile photo of tommls
    tommls
    Participant

    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

  • #41379
    Profile photo of Dan Potter
    Dan Potter
    Participant

    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.

    • This reply was modified 6 months, 1 week ago by Profile photo of Dan Potter Dan Potter.
    • This reply was modified 6 months, 1 week ago by Profile photo of Dan Potter Dan Potter.
  • #41411
    Profile photo of tommls
    tommls
    Participant

    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

    • This reply was modified 6 months, 1 week ago by Profile photo of tommls tommls.
  • #41414
    Profile photo of tommls
    tommls
    Participant

    @Dan if you edit your reply and use

    
    

    tags the code will display better.

  • #41416
    Profile photo of Dan Potter
    Dan Potter
    Participant

    I tried the pre tags as well.

    This has a bunch of lessthan br greaterthan's

    
    
    
    
    
    
    
    
    • This reply was modified 6 months, 1 week ago by Profile photo of Dan Potter Dan Potter.
    • This reply was modified 6 months, 1 week ago by Profile photo of Dan Potter Dan Potter.
    • #41421
      Profile photo of tommls
      tommls
      Participant

      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

  • #41424
    Profile photo of Dan Potter
    Dan Potter
    Participant

    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

    • #41426
      Profile photo of tommls
      tommls
      Participant

      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

  • #41430
    Profile photo of Dan Potter
    Dan Potter
    Participant

    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"

  • #41432
    Profile photo of Jack Neff
    Jack Neff
    Participant

    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.

    • #41436
      Profile photo of tommls
      tommls
      Participant

      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

  • #41434
    Profile photo of tommls
    tommls
    Participant

    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

  • #41438
    Profile photo of Jack Neff
    Jack Neff
    Participant

    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.

  • #41440
    Profile photo of Dan Potter
    Dan Potter
    Participant

    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...

    • This reply was modified 6 months, 1 week ago by Profile photo of Dan Potter Dan Potter.
  • #41443
    Profile photo of Jack Neff
    Jack Neff
    Participant

    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 = @().

    • #41445
      Profile photo of tommls
      tommls
      Participant

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

  • #41455
    Profile photo of Jack Neff
    Jack Neff
    Participant

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

  • #41457
    Profile photo of Jack Neff
    Jack Neff
    Participant

    Yea just looked at this again. Ignore my last two posts. Keep everything inside the foreach loop. Don't change $Events, you want that to be overwritten each iteration. It's the $Body = "Reported on $Date – $DC" line that needs to be changed to $Body +=. This way $Body isn't getting wiped out each time the loop iterates. You will have to define $Body as an array above the foreach loop though. And yea figure out some way to generate some sort of separator in between the dc reports since they'll all be mashed into the same email.

    Sorry for the confusion! Carry on.

  • #41674
    Profile photo of tommls
    tommls
    Participant

    With Jack's most recent suggestions I got it all working.
    I have one foreach to create and store the daily html report file, which looks nicer than the email.
    I have one foreach to put all the stuff into an email and send it to me nightly.
    Thank you, Tom

You must be logged in to reply to this topic.