I've created an advanced function to send out e-mails based on the answer proposed by Mjolinor. However, I'm facing difficulties to have it accept the HTML code block. It's complaining about the System.String
format that cannot be converted to System.Management.Automation.SwitchParameter
.
For my HTML-code I'm using a here string, which works fine when used like Send-MailMessage -BodyAsHtml $HTML
but not when I try it as below. And I can't seem to figure out how to convert it so it does work.
The error:
An error occurred while enumerating through a collection: Collection was modified; enumeration operation may not execute..
At S:\Test.ps1:168 char:9
+ $EmailParams.keys | Where {$EmailParams.$_ -eq $null} | foreach {$EmailP ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Collecti...tableEnumerator:HashtableEnumerator) [], RuntimeException
+ FullyQualifiedErrorId : BadEnumeration
Failed to send email to User@domain.net due to: Cannot convert 'System.String' to the type 'System.Management.Automation.SwitchParameter' required by parameter 'BodyAsHtml'.
The code:
$HTML = @"
<!DOCTYPE html>
<html><head><style type="text/css">
body {font-family:verdana;background-color:white;}
h1 {background-color:black;color:white;margin-bottom:5px;}
h2 {background-color:lightGrey;margin-top:5px;}
h3 {margin-left:10px;font-size: 14px;}
p {font-size: 14px;margin-left:10px;}
p.italic {font-style: italic;font-size: 12px;}
table, td, th {font-size: 14px;border-collapse: collapse; border: 1px lightGrey; padding: 3px; text-align: left; padding-right:10px;}
li {font-size: 14px;}
base {target="_blank"}
</style></head><body>
<h1> $(if(!$ScriptName){"Test"}else{$ScriptName})</h1>
<h2> The following has been reported:</h2>
$Messages
</body></html>
"@
$EmailParams = @{
To = $To
Cc = $Cc
From = $From
Subject = $Subject
BodyAsHtml = $HTML
Priority = $Priority
SMTPServer = $SMTPserver
Attachments = $Attachment
ErrorAction = 'Stop'
}
$EmailParams.keys | Where {$EmailParams.$_ -eq $null} | foreach {$EmailParams.Remove($_)}
Try { Send-MailMessage @EmailParams }
Catch { "Failed to send email to $($To) due to: $_" }
Finally {}
This person had a similar problem, but that was only to come to a System.String
for the -Body
.
Thank you for your help.
There are 2 things wrong here:
BodyAsHtml
is a boolean ($True
), so you need to useBody
to provide your HTML code.- You can't immediately remove stuff from a hashtable. So you need 2
foreach
loops.
Full answer:
$HTML = @"
<!DOCTYPE html>
<html><head><style type="text/css">
body {font-family:verdana;background-color:white;}
h1 {background-color:black;color:white;margin-bottom:5px;}
h2 {background-color:lightGrey;margin-top:5px;}
h3 {margin-left:10px;font-size: 14px;}
p {font-size: 14px;margin-left:10px;}
p.italic {font-style: italic;font-size: 12px;}
table, td, th {font-size: 14px;border-collapse: collapse; border: 1px lightGrey; padding: 3px; text-align: left; padding-right:10px;}
li {font-size: 14px;}
base {target="_blank"}
</style></head><body>
<h1> $(if(!$ScriptName){"Test"}else{$ScriptName})</h1>
<h2> The following has been reported:</h2>
$Messages
</body></html>
"@
$EmailParams = @{
To = $To
Cc = $Cc
Bcc = $Bcc
From = $From
Subject = $Subject
Body = $HTML
BodyAsHtml = $True
Priority = $Priority
SMTPServer = $SMTPserver
Attachments = $Attachments
ErrorAction = 'Stop'
}
$list = New-Object System.Collections.ArrayList
foreach ($h in $EmailParams.Keys) {
if ($($EmailParams.Item($h)) -eq $null) {
$null = $list.Add($h)
}
}
foreach ($h in $list) {
$EmailParams.Remove($h)
}
Try {
Send-MailMessage @EmailParams
Write-Verbose "Send-Mail: Sending mail to: $To"
}
Catch {
"Failed to send email to $($To) due to: $_"
}