I wrote my own function to send out e-mails to end-users in HTML-format. This works flawless to one user or multiple users if I use the following format for the field To: within my script:
$MailTo = "<User1@domain.com>", "<User2@domain.com>"
However, when I try to start a scheduled task in Windows with the same arguments, PowerShell complains about Cannot find an object with identity User1@domain.com or the mail is only sent to one user and not both.
The way I launch the script as scheduled task or from the prompt, which does not work:
powershell -File "S:\Script\Send_Mail.ps1" -MailTo "<User1@domain.com>", "<User2@domain.com>"
Even if I try one of these arguments, only one mail gets sent:
-MailTo "<User1@domain.com>, <User2@domain.com>"
-MailTo "User1@domain.com, User2@domain.com"
I found this but it was not really clear what I did wrong. Thank you for your help guys.
The script:
[CmdletBinding(SupportsShouldProcess=$True)]
Param (
[parameter(Mandatory=$true,Position=0)]
[String[]] $MailTo,
[parameter(Mandatory=$true,Position=1)]
[String[]] $Subject,
[parameter(Mandatory=$true,Position=2)]
[String[]] $Message1
)
Function Send-Mail {
[CmdletBinding(SupportsShouldProcess=$True)]
Param (
[parameter(Mandatory=$true,Position=0)]
[String[]] $To,
[parameter(Mandatory=$true,Position=1)]
[String[]] $Subject,
[parameter(Mandatory=$true,Position=2)]
[String[]] $Message1,
[parameter(Mandatory=$false,Position=3)]
[String[]] $Message2
)
# Set SMTP server name
$PSEmailServer = "SMTP.Server"
# Check where we've been launched from
if($PSISE) {
$LaunchedFrom = "Windows PowerShell ISE"
}
else {
$LaunchedFrom = "Scheduled task or console (not ISE)"
}
$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>
<p>$Message1</p>
<p>$Message2</p>
<h2> About</h2>
<p><table>
$(if($ScriptStart){$("<tr><th>Start time</th><td>{0:00}/{1:00}/{2:00} {3:00}:{4:00} ({5})</td></tr>" -f `
$ScriptStart.Day,$ScriptStart.Month,$ScriptStart.Year,$ScriptStart.Hour,$ScriptStart.Minute,$ScriptStart.DayOfWeek)})
$(if($ScriptRunTime){"<tr><th>Total runtime</th><td>$ScriptRunTime</td></tr>"})
$(if($LogFolder){"<tr><th>Log folder</th><td>$("<a href=`""$LogFolder"`">$LogFolder</a>")</td></tr>"})
$(if($PSCommandPath){"<tr><th>Script location</th><td>$PSCommandPath</td></tr>"})
<tr><th>Launched from</th><td>$LaunchedFrom</td></tr>
</tr><tr><th>Server</th><td>$env:computername</td></tr>
</tr></tr><tr><th>Whoami</th><td>$("$env:USERDNSDOMAIN\$env:USERNAME")</td>
</tr><tr><th>Help</th><td><a href="http://www.google.com" target="_blank">Google</a></td></tr>
</table></p><p class=italic>"$(Get-Content "S:\Input\Extra\Quotes.txt" | Get-Random -ErrorAction SilentlyContinue)"</p1>
</body></html>
"@
# Mail content
Write-Verbose "Function Send-Mail: Sending mail"
Send-MailMessage -To $To -From "$(if(!$ScriptName){"Test"}else{$ScriptName}) PowerShell@$env:computername" `
-Subject "$Subject" `
-BodyAsHtml "$HTML"
}
Send-Mail $MailTo $Subject $Message1
The solution
Correct the parameters to only accept an array where it's needed (multiple $MailTo):
Param (
[parameter(Mandatory=$true,Position=0)]
[String[]] $MailTo,
[parameter(Mandatory=$true,Position=1)]
[String] $Subject,
[parameter(Mandatory=$true,Position=2)]
[String] $Message1
)
To run this from a scheduled task in Windows you can use these formats:
powershell "S:\Script\Send_Mail.ps1" -ImportFile "S:\Script\Servers.csv" -MailTo "User1@domain.com", "User2@domain.com"
powershell -ExecutionPolicy Bypass "S:\Script\Send_Mail.ps1" -ImportFile "S:\Script\Servers.csv" -MailTo "User1@domain.com", "User2@domain.com"
These formats are not accepted and will result in syntax errors or not all users receive their e-mail:
powershell -File "S:\Script\Send_Mail.ps1" -ImportFile "S:\Script\Servers.csv" -MailTo "User1@domain.com, User2@domain.com"
powershell -File "S:\Script\Send_Mail.ps1" -ImportFile "S:\Script\Servers.csv" -MailTo '"User1@domain.com", "User2@domain.com"'
powershell "S:\Script\Send_Mail.ps1" -ExecutionPolicy Bypass -ImportFile "S:\Script\Servers.csv" -MailTo "User1@domain.com, User2@domain.com"
All the lines above can be pasted for testing in the PowerShell ISE, so you can see the errors instead of relying on the scheduled task to tell you. I hope it helps you guys as it was freaking me out :P