Home > Blockchain >  Powershell - Get-WinEvent - send email with message from Event
Powershell - Get-WinEvent - send email with message from Event

Time:06-20

I am new in powershell. I want to get the events from Task Scheduler/Operational with code of failure, and send an email with all events in the body.

# Get all events from yesterday with ID=103 and Text, put in table and send email
   
# Get the event entries.
$eventEntries = & {Get-WinEvent  -FilterHashtable @{ LogName='Microsoft-Windows-TaskScheduler/Operational'; StartTime=(Get-Date).AddDays(-1); ID='103'} | 
    Where {$_.Message.Contains('Task Scheduler failed to start instance')} | 
    select -Property ID,TimeCreated,Message |ft -wrap}
            
# Create a table row for each entry.
$array = @()

foreach ($eventEntry in $eventEntries)
{
     $array  = $eventEntry
}
$array | Format-table

# Create the email.
$MailFrom = "[email protected]"
$MailTo = "[email protected]"
$Subject = "EventLogAlert"
$email = New-Object System.Net.Mail.MailMessage( $MailFrom , $MailTo )
$email.Subject = $Subject
$email.IsBodyHtml = $true
$email.Body = @"
<table style="width:100%;border">
     <tr>
         <th style="text-align: center; padding: 5px;">ID</th>
         <th style="text-align: center; padding: 5px;">TimeCreated</th>
         <th style="text-align: center; padding: 5px;">Message</th>
        </tr>
    
    $array
    </table>
"@

# Send the email.
$SmtpServer = "smtp.mail.outlook.com"
$SmtpPort = 587
$SmtpUser = "[email protected]"
$SmtpPassword = "passwordexample"
$SMTPClient=New-Object System.Net.Mail.SmtpClient($SmtpServer,$SmtpPort)
$SMTPClient.EnableSsl=$true
$SMTPClient.Credentials= New-Object System.Net.NetworkCredential($SmtpUser,$SmtpPassword);
$SMTPClient.Send($email)

The $array is created with values in it, can viewed with echo $eventEntries The result $email is not with values from table, it give this text

Microsoft.PowerShell.Commands.Internal.Format.FormatStartData Microsoft.PowerShell.Commands.Internal.Format.GroupStartData Microsoft.Powershell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData Microsoft.PowerShell.Commands.Internal.Format.GroupEndData Microsoft.PowerShell.Commands.Internal.Format.FormatEndData 

Can somebody help me to write correct code to view all events in email.

And additionally, to create for each event an email separately.

Thanks in advance!

CodePudding user response:

You should not use Format-Table if you plan on using the data any further, because that cmdlet is only meant for display purposes.

Try the code below:

$yesterday = (Get-Date).AddDays(-1).Date   # set to midnight
$filter    = @{LogName='Microsoft-Windows-TaskScheduler/Operational'; StartTime=$yesterday; ID='103'}
$events    = Get-WinEvent -FilterHashtable $filter -ErrorAction SilentlyContinue | 
             Where-Object {$_.Message -like '*Task Scheduler failed to start instance*'} | 
             Select-Object -Property TaskDisplayName,ID,TimeCreated,Message

$style = @'
<style>
    body {font-family: Calibri, Tahoma, Helvetica, sans-serif; color: black;}
    table {width: 100%; border-width: 1px; border-style: solid; border-color: black; border-collapse: collapse;}
    th {text-align: center; padding: 5px; background-color: #6495ED; color: white;}
    td {border-width: 1px; padding: 3px; border-style: solid; border-color: black;}
</style>
'@

# to use for both the email as the subject for this email
$subject = 'EventLogAlert {0:yyyy-MM-dd HH:mm:ss}' -f (Get-Date)

# create the email body using the style above for the table
$body = $events | ConvertTo-Html -Head $style -PreContent "<h2>$subject</h2>"

# Create the email.
$MailFrom = "[email protected]"
$MailTo   = "[email protected]"
$email    = New-Object System.Net.Mail.MailMessage($MailFrom, $MailTo)
$email.Subject    = $subject
$email.IsBodyHtml = $true
$email.Body       = $body -join [environment]::NewLine

# Send the email.
$SmtpServer   = "smtp.mail.outlook.com"
$SmtpPort     = 587
$SmtpUser     = "[email protected]"
$SmtpPassword = "passwordexample"
$SMTPClient   = New-Object System.Net.Mail.SmtpClient($SmtpServer, $SmtpPort)
$SMTPClient.EnableSsl   = $true
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential($SmtpUser, $SmtpPassword);
$SMTPClient.Send($email)

Notes:

  • I'm using the -like operator rather than the .Contains() string method, because the latter is case-sensitive
  • I have set yesterda's date to midnight by appending .Date
  • The styling is all up to you, this is just an example you may or may not like..

CodePudding user response:

We do something similar with a script that sends a weekly count of our Office 365 license allocation to a couple of distribution groups. Perhaps this might help you get your script up and running:

Import-Module AzureAD
$username = "[email protected]"
$pwd = Get-Content "c:\scripts\LicenseCheckPW.txt" | ConvertTo-SecureString -Key (1..32)
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $pwd
Connect-MsolService -Credential $cred

$outarray = @()

foreach($sku in (Get-MsolAccountSku))
{
    $name = $sku.AccountSkuID
    $partno = $sku.SkuPartNumber
    $active = $sku.ActiveUnits
    $used = $sku.ConsumedUnits
    $remaining = ($sku.ActiveUnits - $sku.ConsumedUnits)
    if($active -eq 0)
    {
        $premaining = 0
    }
    else
    {
        $premaining = [math]::Round(100-($sku.ConsumedUnits / $sku.ActiveUnits * 100), 2)
    }
    $outobj = New-Object Object
    $outobj | Add-Member -Type Noteproperty -Name "Name" $name
    $outobj | Add-Member -Type Noteproperty -Name "Part No" $partno
    $outobj | Add-Member -Type Noteproperty -Name "Active Units" $active
    $outobj | Add-Member -Type Noteproperty -Name "Consumed Units" $used
    $outobj | Add-Member -Type Noteproperty -Name "Remaining Units" $remaining
    $outobj | Add-Member -Type Noteproperty -Name "Percentage Remaining" $premaining
    $outarray  = $outobj
}

$style = "<head><title>Office365 License Check</title></head><style>"
$style  = "BODY{background-color:peachpuff; text-align: center;}"
$style  = "TABLE{border-width:1px; border-style: solid; border-color: black; border-collapse: collapse; text-align: center;}"
$style  = "TH{border-width: 1px; padding: 5px; border-style: solid; border-color: black; background-color: thistle;}"
$style  = "TD{border-width: 1px; padding: 5px; border-style: solid; border-color: black; background-color: palegoldenrod;}"
$style  = "</style>"

$body = "<h2>Office365 License Check</h2><p>Output generated: "   (Get-Date -Format D)

$html = ($outarray | ConvertTo-HTML -head $style -body $body)

$server = "smtp.exchange.server.com"
$msg = New-Object Net.Mail.MailMessage
$smtp = New-Object Net.Mail.SmtpClient($server)
$msg.From = "[email protected]"
$msg.To.Add("[email protected]")
$msg.To.Add("[email protected]")
$msg.Subject = "Corporate O365 License Check"
$msg.Body = $html
$msg.IsBodyHtml = $true
$smtp.Send($msg)
  • Related