Variable not expanding in double quoted here string - powershell

The variable $reperr is not expanding inside the double quoted here-string. When the scriptblock completes, $reperr does have a value, but it will not print in the here string, all i get in the body is the flat text "There are currently errors with domain.com AD replication."
Clear-Variable -name "reperr"
$reperr = Get-ADReplicationPartnerMetadata -target * |? {$_.ConsecutiveReplicationFailures -eq "0"} |select Server, ConsecutiveReplicationFailures
$smtpserver = "10.25.172.2"
#$recipients = "email#emailaddy.com"
$recipients = "user#doamin.com"
$sender = "ad_repl_status#domain.com"
$subject = "DOMAIN.COM ACTIVE DIRECTORY REPLICATION ISSUES DETECTED!"
$body = #"
There are currently errors with domain.com AD replication.
$reperr
"#
if (!$reperr)
{
Write-Host "AD REPLICATION IS CLEAN"
}
else
{
Send-MailMessage -Priority High -SmtpServer $smtpserver -From $sender -To $recipients -Subject $subject -Body $body
}

Related

Return to language specific variable in the -body parameter from (Send-MailMessage)

I have defined several variables with different Body Content that I can refence later in Send-MailMessage command with the -Body Parameter.
$bodyit = #"
Hello Italy
"#
$bodyde = #"
Hello Germany
"#
$bodymx = #"
Hello Mexico
"#
$bodye = #"
Hello International
"#
if ($var -eq "IT"){
return $bodyit
}elseif ($var -eq "DE"){
return $bodyde
}elseif ($var -eq "MX"){
return $bodymx
}else {return $bodye}
Send-MailMessage -from "..." -to "..." -subject "..." -smtp "..." -Body $return to specific $body
How can I achieve that I get the correct return type in the Send-MailMessage?
Many thanks in advance.
Try using a switch instead of multiple if, also store the value you actually want into $body and use $body in the Send-Mail for the correct response.
Try it like this:
switch ($var)
{
IT {
$body = #"
Hello Italy
"#
}
DE {
$body = #"
Hello Germany
"#
}
MX {
$body = #"
Hello Mexico
"#
}
default {
$body = #"
Hello International
"#
}
}
Send-MailMessage -from "..." -to "..." -subject "..." -smtp "..." -Body $body
You can follow your approach compounding the variable name from body and $var using the cmdlet Get-Variable
If ($var -in 'it','de','mx'){
$Body = (get-variable -name "body$var").Value
} else {
$Body = $bodye
}

Powershell Script which reads text files in smaller batches.

I have come across an issue when sending SMTP email, to a number of email address approx. 200. I am looking for a script in which it reads a .txt file containing the 200 email addresses and in smaller batches, sends an generic SMTP message using the script below.
The script which sends the generic email is below:
$to = "TO EMAIL"
$smtp = "SMTP Server"
$from = "FROM EMAIL"
$subject = "Subject"
$body = "EMAIL BODY"
send-MailMessage -SmtpServer $smtp -To $to -Bcc (Get-Content "\\FILE Location") -From $from -Subject $subject -Body $body -BodyAsHtml -Priority high
Any help would be appreciated.
Here's one solution (there might be other/better ways):
$to = "TO EMAIL"
$smtp = "SMTP Server"
$from = "FROM EMAIL"
$subject = "Subject"
$body = "EMAIL BODY"
$Recipient = Get-Content "emails.txt"
$NumberOfBatches = [int]($Recipient.count / 50)
For ($i = 0; $i -lt $NumberOfBatches; $i++) {
$Emails = $Recipient | Select -First 50 -Skip ($i * 50)
Send-MailMessage -SmtpServer $smtp -To $to -Bcc $Emails -From $from -Subject $subject -Body $body -BodyAsHtml -Priority high
}
This loads the list of emails address in to a variable named $Recipient.
It then gets a count for how many batches there would need to be to send it 50 emails at a time, casting this as [int] to get a round number.
It then uses a For loop to do the number of batches defined, and uses the Select-Object cmdlet to filter the list of emails by the defined batches, by using -First and -Skip.

send-mailmessage cmdlet does not accept list variable

I have a sharepoint list that has a people column - I am trying to write a PS script that would email a person in the people column. Now the problem I am facing is I can't substitute a list variable into the send-mailmessage cmdlet i/e the following does not work:
cls
if((Get-PSSnapin | Where {$_.Name -eq "Microsoft.SharePoint.PowerShell"}) -eq $null) {
Add-PSSnapin Microsoft.SharePoint.PowerShell;
}
$sourceWebURL = "http://sp2k10lab"
$sourceListName = "miztest"
$spSourceWeb = Get-SPWeb $sourceWebURL
$spSourceList = $spSourceWeb.Lists[$sourceListName]
$spSourceItems = $spSourceList.GetItems()
$spSourceItems | ForEach-Object {
$_name=$_['name']
$_email=$_['email']
send-mailmessage -from "support#XXXXXX" -to $_email -subject "Regulatory Reminder Notice" -body "Tboooooooooooooooooooooooooitle is overdue by $_diff days" -priority High -dno onSuccess, onFailure -smtpServer XXXXXXXx
}
$_email is where the email address is stored in the list - however - when I try to substitute it into my send-mailmessage cmdlet it does not - the sendmail-message cmdlet works only if I explicitly set an email addy in there i.e the following works
send-mailmessage -from "support#XXXXXX" -to "foo_miz <'abc#XXXXX.com'>" -subject "Regulatory Reminder Notice" -body "Tboooooooooooooooooooooooooitle is overdue by $_diff days" -priority High -dno onSuccess, onFailure -smtpServer XXXXXXX
Should I be using a different cmdlet for this purpose - or is this just me being silly with my syntax?
Thanks for any help - would really appreciate a way to do this.
First of all you should not use the '_' character at the begining of your vars, just becaise $_ is a specific var in PowerShell.
Second, here is the way I use Send-MailMessage and it works :
$mailServer = "smtp.myserver.com"
$encoding=[System.Text.Encoding]::UTF8
$cred = $null
$body = "Are you serious !"
$DesAdressesDest = "Nicolas S <nicolas.sc#Elyse.fs>","Francois H <francois.h#Elyse.fr>"
$Subject = "About French bashing"
send-mailmessage -SmtpServer $mailServer `
-to $DesAdressesDest `
-from "JP Blanc <jpb#people.com>"`
-subject $Subject `
-body $Body -BodyAsHtml `
-ErrorAction continue `
-Encoding $encoding

Run built-in cmdlet with parameters that may or may not be specified

I've got a function in my script that wraps up the send-mailmessage cmdlet and does a bit of logic before sending out each email.
My question is how do I create the argument list to feed into send-mailmessage so that Cc, Bcc, and Attachments are optional.
What I'd done before is just a few if statements. But adding -Cc to the mix, that will be 9 if statements instead of the current 4. I figure I'm over-thinking this and there's got to be a simpler way.
Stripped down Function:
Function Send-Email ($To, $Cc, $Bcc, $Subject, $From, $Body, $Attachments)
{
#Some more code goes here that sometimes modifies the incoming parameters
$EmailServer = my.mail.server
Try
{
#Need to add ability for $Cc to be optional
if ($Attachments -and $Bcc) {send-mailmessage -to $To -Cc $Cc -Bcc $Bcc -subject $Subject -From $From -body $Body -smtpserver $EmailServer -attachments $Attachments -ErrorAction "Stop"}
if ($Attachments -and -not $Bcc) {send-mailmessage -to $To -Cc $Cc -subject $Subject -From $From -body $Body -smtpserver $EmailServer -attachments $Attachments -ErrorAction "Stop"}
if ($Bcc -and -not $Attachments) {send-mailmessage -to $To -Cc $Cc -Bcc $Bcc -subject $Subject -From $From -body $Body -smtpserver $EmailServer -ErrorAction "Stop"}
if (-not $Attachments -and -not $Bcc) {send-mailmessage -to $To -Cc $Cc -subject $Subject -From $From -body $Body -smtpserver $EmailServer -ErrorAction "Stop"}
}
Catch [system.exception]
{
"Failed to send email to $($To) due to: $_" #Logging removed for SO example code
}
Finally
{}
}
I've tried generating the arguments as one long string or also as an array of strings, then using invoke-expression. I've tried the same, but using the '&' sign to execute the cmdlet.
I just get prompted for the parameters by the shell when I try that.
PS E:\script> invoke-expression 'send-mailmessage $a'
cmdlet Send-MailMessage at command pipeline position 1
Supply values for the following parameters:
From:
PS E:\script> & send-mailmessage $a
cmdlet Send-MailMessage at command pipeline position 1
Supply values for the following parameters:
From:
I've tried setting $Cc as $Null, or $False, or a null string "", but send-mailmessage complains of invalid parameters.
I feel like I'm missing something simple here, but in my mind, the function should look something like this invalid example:
Function Send-Email ($To, $Cc, $Bcc, $Subject, $From, $Body, $Attachments)
{
#Some more code goes here that sometimes modifies the incoming parameters
$EmailServer = my.mail.server
if ($Cc) {$CcArg = "-Cc $Cc"}
if ($Bcc) {$BccArg = "-Bcc $Bcc"}
if ($Attachments) {$AttachArg = "-Attachments $Attachments"}
Try
{
send-mailmessage -to $To ($CcArg) ($BccArg) -subject $Subject -From $From -body $Body -smtpserver $EmailServer $AttachArg -ErrorAction "Stop"
}
Catch [system.exception]
{
"Failed to send email to $($To) due to: $_" #Logging removed for SO example code
}
Finally
{}
}
Thanks for any thoughts or suggestions.
Ah hah!
Found this post: Inline expansion of powershell variable as cmdlet parameter?
So function will look something like (Not fully tested, but the principle works):
Function Send-Email ($To, $Cc, $Bcc, $Subject, $From, $Body, $Attachments)
{
#Some more code goes here that sometimes modifies the incoming parameters
$EmailServer = my.mail.server
$MoreArgs = #{}
if ($Cc) {$MoreArgs.Add("Cc",$Cc)}
if ($Bcc) {$MoreArgs.Add("Bcc",$Bcc)}
if ($Attachments) {$MoreArgs.Add("Attachments",$Attachments)}
Try
{
send-mailmessage -to $To -subject $Subject -From $From -body $Body -smtpserver $EmailServer -ErrorAction "Stop" #MoreArgs
}
Catch [system.exception]
{
"Failed to send email to $($To) due to: $_" #Logging removed for SO example code
}
Finally
{}
}
Another option that eliminates all the Ifs.
$EmailParams = #{
To = $To
Cc = $Cc
From = $From
Subject = $Subject
Body = $body
SMTPServer = $MailServer
Attachments = $Attachments
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 {}

Email Subject showing Encoding

I am using send-mail message to send email to our Support System.
But when it send email it shows the subject line like this screen!
=?us-ascii?Q?R899076:Aman:System Summary ?=
In Subject I am using the variable:
$vUserName = (Get-Item env:\username).Value
$vComputerName = (Get-Item env:\Computername).Value
$subject = "$vComputerName : $vUserName : System Summary"
and then
send-MailMessage -SmtpServer Smtp-local -To $to -From $from -Subject $subject -Body $body -BodyAsHtml -Priority High
But when I recieve this email in Outlook it looks fine any Idea?
Actually this a approx 150 lines script and the body of email and smtp server are already specified in the server.
yes I tried the $subject = "$env:ComputerName : $env:UserName : System Summary" variable and the result is same.
yes I have tried the - encoding option and it gives an error
Send-MailMessage : Cannot bind parameter 'Encoding'. Cannot convert the "utf8" value of type "Syste
m.String" to type "System.Text.Encoding".
At D:\PowerShell\MyScripts\SystemInfo\SysInfo-V6-test[notfinal].ps1:151 char:84
+ send-MailMessage -SmtpServer $smtp -To $to -From $from -Subject $subject -Encoding <<<< utf8 -B
ody $body -Attachments "$filepath\$name.html" -BodyAsHtml -Priority High
+ CategoryInfo : InvalidArgument: (:) [Send-MailMessage], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.SendMai
lMessage
Any clue?
You could write a custom function to send using .net instead of using the Send-MailMessage cmdlet. It's a lot clunkier, but gets round the problem.
Something like this:
Function SendEmail ($emailFrom, $emailTo, $subject, $body, $attachment) {
# Create from/to addresses
$from = New-Object System.Net.Mail.MailAddress $emailFrom
$to = New-Object System.Net.Mail.MailAddress $emailTo
# Create Message
$message = new-object System.Net.Mail.MailMessage $from, $to
$message.Subject = $subject
$message.Body = $body
$attachment = new-object System.Net.Mail.Attachment($attachment)
$message.Attachments.Add($attachment)
# Set SMTP Server and create SMTP Client
$server = <your server>
$client = new-object system.net.mail.smtpclient $server
# Send the message
"Sending an e-mail message to {0} by using SMTP host {1} port {2}." -f $to.ToString(), $client.Host, $client.Port
try {
$client.Send($message)
"Message to: {1}, from: {0} has beens successfully sent" -f $from, $to
}
catch {
"Exception caught in CreateTestMessage: {0}" -f $Error.ToString()
}
}
(Thanks to Thomas Lee (tfl#psp.co.uk) - I tweaked this from his code at http://powershell.com/cs/media/p/357.aspx)
The Send-MailMessage cmdlet doesn't have any output after you send emails, I wonder where the output comes from? Can you include the command you use and the output?
As to your subject line, you can reduce it to one line only:
$subject = "$env:ComputerName : $env:UserName : System Summary"
The Send-MailMessage has an Encoding parameter, have you tried it?
This happened to me when I used Send-MailMessage with the default encoding (ASCII) when there were spaces in the subject.
First, to answer the question about the Encoding parameter: You are trying to pass it as a string (ie "-Encoding ASCII"), when you should be using this type of syntax instead: "-Encoding ([System.Text.Encoding]::ASCII)".
This "encoding in the subject" issue happened to me, and I narrowed it down to spaces in the subject. To demonstrate:
This will not contain encoding in the subject:
Send-MailMessage -To "alice#example.com" -From "bob#example.com" -Smtp "localhost" -Subject "one" -BodyAsHtml "body1" -Encoding ([System.Text.Encoding]::ASCII)
But this will:
Send-MailMessage -To "alice#example.com" -From "bob#example.com" -Smtp "localhost" -Subject "one two" -BodyAsHtml "body1" -Encoding ([System.Text.Encoding]::ASCII)
Note that the only material difference is the space in the subject.
If I specify UTF8 as the encoding, there is no encoding in the subject:
Send-MailMessage -To "alice#example.com" -From "bob#example.com" -Smtp "localhost" -Subject "one" -BodyAsHtml "body1" -Encoding ([System.Text.Encoding]::UTF8)
But as you say, it looks fine in Outlook, so I presume that the subject is correct. I'm not an expert on email formats or text-encoding, so I won't speculate as to why.