Good — you were close. The problem was the type/shape of what you put into $msg. Send-MailMessage expects a plain string (or byte-encodable text) for -Body. If $msg contains EventRecord objects, arrays, XML nodes, or a formatted object stream, casting ([string]$msg) can produce odd output. The reliable approach is to extract/format the text you want and convert that to a single string (Out-String or -join) before passing it to -Body.
Here are several safe, copy/paste-ready ways to build $msg and call Send-MailMessage.
1) Simple — send the Message field from the latest matching event
get one event
$evt = Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-ServerEssentials/Admin'; Id=262} -MaxEvents 1
extract the textual Message property
$msg = $evt.Message
send
Send-MailMessage -SmtpServer 'smtp.smtp2go.com' -Port 587 -UseSsl -Credential $cred `
-From '
sam@samcox.org' -To '
you@domain.tld' -Subject "Event 262" -Body $msg -Encoding UTF8
2) Multiple events — join their Message texts into one body
$events = Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-ServerEssentials/Admin'; Id=262} -MaxEvents 10
$msg = ($events | ForEach-Object { $
.TimeCreated.ToString('u') + " - EventId:$($.Id)
n" + $_.Message }) -join "r
nr
n----r
n" Send-MailMessage -SmtpServer 'smtp.smtp2go.com' -Port 587 -UseSsl -Credential $cred
-From '
sam@samcox.org' -To '
you@domain.tld' -Subject "Recent Event 262s" -Body $msg -Encoding UTF8
3) If you want the formatted output you saw with Format-List
(Format-* returns formatted objects for the console, not a string — use Out-String)
$msg = Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-ServerEssentials/Admin'; Id=262} -MaxEvents 5 |
Select-Object TimeCreated, RecordId, Id, LevelDisplayName, ProviderName, Message |
Format-List | Out-String -Width 4096
Send-MailMessage -SmtpServer 'smtp.smtp2go.com' -Port 587 -UseSsl -Credential $cred `
-From '
sam@samcox.org' -To '
you@domain.tld' -Subject "Event 262 (formatted)" -Body $msg -Encoding UTF8
Notes and tips
- Use -ExpandProperty when you want raw property text:
Get-WinEvent ... | Select-Object -ExpandProperty Message
This returns plain strings (not objects), which you can -join.
- If your message contains newlines, Send-MailMessage handles them fine. Use
n orr`n for line breaks when joining.
- If you had “gibberish” when casting to [string], you were probably casting an object type (EventRecord) or an XML blob. The approaches above return plain text.
- If you need HTML body, build HTML into $msg and use the -BodyAsHtml switch:
Send-MailMessage ... -Body $msg -BodyAsHtml
- Use -Encoding UTF8 to avoid character set problems for non-ASCII characters.
Example end-to-end (pasteable)
get last event 262
$evt = Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-ServerEssentials/Admin'; Id=262} -MaxEvents 1
create a readable body
$msg = "Time: $($evt.TimeCreated)
nEventID: $($evt.Id)nSource: $($evt.ProviderName)
nn$($evt.Message)"
SMTP credential object
$cred = New-Object System.Management.Automation.PSCredential('SMTP2GO_USERNAME',(ConvertTo-SecureString 'SMTP2GO_PASSWORD' -AsPlainText -Force))
send
Send-MailMessage -SmtpServer 'smtp.smtp2go.com' -Port 587 -UseSsl -Credential $cred `
-From '
sam@samcox.org' -To '
you@domain.tld' -Subject "ServerEssentials Event 262" -Body $msg -Encoding UTF8
If you paste the exact code you used to build $msg (and the error text you saw when using -Body $msg), I’ll point out precisely what type you actually had and what change will fix it.