0

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 = "helpdesk@mydomain.com"
$MailTo = "myemail@mydomain.com"
$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 = "helpdesk@mydomain.com"
$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!

rabocii
  • 3
  • 2

2 Answers2

1

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 = "helpdesk@mydomain.com"
$MailTo   = "myemail@mydomain.com"
$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     = "helpdesk@mydomain.com"
$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..
Theo
  • 57,719
  • 8
  • 24
  • 41
  • Very cool! It works! I see about Format-table, thanks! How can put in Subject the TimeCreated of the Event? – rabocii Jun 20 '22 at 12:34
  • and also, in Subject can be put the name of the task? how can I see, every task name begin with "\" and it is between the words "of" and "task" – rabocii Jun 20 '22 at 12:45
  • @deltaplaned I have added property `TaskDisplayName` in the output. About putting the TimeCreated in the subject... Since you are likely to get more than one single event, which task date to choose? Also, this is totally unnecessary, since the table with info already shows that date for each of the events. – Theo Jun 20 '22 at 13:49
  • @deltaplaned Being new to the platform since today, may I point you to the [tour]? It's an easy read and among other things, it shows you what to do if someone answeres your question – Theo Jun 20 '22 at 13:51
-1

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 = "user@tenant.onmicrosoft.com"
$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 = "sender@domain.com"
$msg.To.Add("recipientgroup1@domain.com")
$msg.To.Add("managementteam@domain.com")
$msg.Subject = "Corporate O365 License Check"
$msg.Body = $html
$msg.IsBodyHtml = $true
$smtp.Send($msg)
LordPupazz
  • 619
  • 3
  • 15
  • Thanks for your script, it can be useful. In my case, the email is created, and can be sent, but I have issue with text in it. – rabocii Jun 20 '22 at 10:16
  • 1
    Please don't dump unrelated code as an answer to a question where the only similarity is that both happen to send emails. – Booga Roo Jun 20 '22 at 10:58