Как отправить уникальные индивидуальные электронные письма? - PullRequest
3 голосов
/ 10 июня 2019

Мне нужно отправить одно уникальное письмо на экспорт разных адресов электронной почты их из .csv файла. У меня есть код, но он просто отправляет сообщение всем из писем в одном письме.

#Import the file that store username and emails
$data = import-csv "C:.csv"

#Declare email content
$email = $data.Email | select -unique

ForEach ($email in $data)
{
$From = "***@gmail.com"
$To = $data.Email
$Subject = "Test"
$Body = "Test"
$SMTPServer = "smtp.gmail.com"
$SMTPPort = "587"
}

#Sending email
Send-MailMessage -From $From -to $To -Subject $Subject `
-Body $Body -SmtpServer $SMTPServer -port $SMTPPort -UseSsl `
-Credential (Get-Credential -Message "Please input valid credentials")

Приведенный выше код работает, но, как уже упоминалось, он отправляет только одно электронное письмо на все адреса электронной почты в файле. Мне нужно, чтобы отправить по одному на каждое письмо.

Ответы [ 3 ]

2 голосов
/ 10 июня 2019

Основная проблема, которую я вижу в вашем коде, заключается в том, что вы сначала создаете массив уникальных адресов электронной почты из файла csv в переменной $email, но позже вы перезаписываете это же значение, используя его в цикле foreach .

Там, на каждой итерации, переменная $email станет полной строкой из файла CSV, что явно не то, что вы ожидаете.

Ниже слегка скорректированная версия вашего кода. Обратите внимание, что я также использовал Splatting , чтобы создать хеш-таблицу со всеми свойствами для командлета Send-MailMessage, чтобы избежать необходимости использовать backtick, который легко игнорировать.

#Import the file that store username and emails
$data = import-csv "D:\mail.csv"

# Get a unique array of email addresses
$addresses = $data.Email | Select-Object -Unique

# Declare Credentials
$creds = (Get-Credential -Message "Please input valid credentials")

# loop through the email addresses array and send a mail to each of them
foreach ($email in $addresses) {
    $splat = @{
        From       = "***@gmail.com"
        To         = $email
        Subject    = "Test"
        Body       = "Test"
        SmtpServer = "smtp.gmail.com"
        Port       = 587
        Credential = $creds
        UseSsl     = $true
    }

    #Sending email
    Send-MailMessage @splat
}

Обратите внимание, что параметр -Port имеет тип Int32, поэтому не следует заключать его в кавычки


Обновление

В соответствии с вашим комментарием, если вы хотите использовать больше полей из CSV-файла, код изменится.
Давайте предположим, что ваш CSV выглядит примерно так:

"User","Email","ManagerEmail"
"Tom","t.somebody@yourcompany.com","el.jeffe@yourcompany.com"
"Dick","d.somebody@yourcompany.com","el.jeffe@yourcompany.com"
"Harry","h.somebody@yourcompany.com","di.rector@yourcompany.com"
"Dick","d.somebody@yourcompany.com","el.jeffe@yourcompany.com"

(обратите внимание, пользователь Дик дублируется)

Затем следующий код будет читать csv, дедуплицировать его в свойстве Email и отправлять электронные письма каждому пользователю:

# Import the file that store username and emails
# and uniquify the objectson property Email
$data = Import-Csv "D:\mail.csv" | Sort-Object -Property Email -Unique

# Declare Credentials
$creds = (Get-Credential -Message "Please input valid credentials")

# loop through the csv objects array and send a mail to each of them
foreach ($item in $data) {
    # every item is an object with properties .User, .Email and .ManagerEmail
    $splat = @{
        From       = "***@gmail.com"
        To         = $item.Email
        Cc         = $item.ManagerEmail
        Subject    = "Hi there {0}" -f $item.User
        Body       = "Test"
        SmtpServer = "smtp.gmail.com"
        Port       = 587
        Credential = $creds
        UseSsl     = $true
    }

    #Sending email
    Send-MailMessage @splat
}

Надеюсь, это поможет

1 голос
/ 10 июня 2019

Согласно комментариям, пожалуйста, найдите скорректированный сценарий и обоснование.

Вы просматривали CSV, но отправляли электронное письмо только один раз.Похоже, что он первоначально отправил бы электронное письмо ОДНОМУ человеку, который является последним в вашем CSV.

Эта версия будет проходить и отправлять электронную почту для каждой строки в CSV.

#Import the file that store username and emails
$data = import-csv "C:.csv"

#Declare email content
$email = $data.Email | select -unique

# Declare Credentials
$creds = (Get-Credential -Message "Please input valid credentials")

ForEach ($email in $data) {
    $From = "***@gmail.com"
    $To = $email.Email
    $Subject = "Test"
    $Body = "Test"
    $SMTPServer = "smtp.gmail.com"
    $SMTPPort = "587"

    #Sending email
    Send-MailMessage -From $From -to $To -Subject $Subject `
    -Body $Body -SmtpServer $SMTPServer -port $SMTPPort -UseSsl `
    -Credential $creds
}
0 голосов
/ 10 июня 2019

Самая важная ошибка, которую вы сделали,

$To = $data.Email

, где вы добавляете все электронные письма в поле To:. Предложение Дрю почти то, что вы хотите следовать, но с одним замечанием. Ваше присвоение $To= должно использовать $email, представляющее отдельный объект из массива, а не весь массив ($data).

$To = $email.Email

Редактировать: Как @ Тео предложено в комментариях, стоит упомянуть, что строка

$email = $data.Email | select -unique

не будет работать, так как вы используете то же имя переменной позже в цикле foreach. Я бы предложил сохранить уникальные адреса электронной почты в другую переменную

$uniqueEmails = $data.Email | select -unique

затем повторить этот

# Change this
ForEach ($email in $data) {
# To this
ForEach ($email in $uniqueEmails ) {

И, конечно, как вы уже сохранили Email значение $uniqueEmails:

# This line
$To = $email.Email
# Should be changed to
$To = $email
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...