Email Send

Hi,

I would like to send an email automatically by the windows task manager. The idea is the subject and email from fields is an array with two dimension or two array. Below part of code.

#******** Here get the previous month ******************************
$lastmonth = (Get-Date).AddMonths(-1).ToString('MMMM')
$year = (get-date).Year
$lastmonth = (Get-Culture).TextInfo.ToTitleCase($lastmonth)
#*******************************************************************
#****************emails from Customers******************************
$emailClientes = @('user1@dom.com';'user2@dom.com')

#*****************Company names*************************************
$clientes = @('company01','company02','company03','company04')


$emailcli = @($clientes, $emailClientes)|
foreach{

$EmailFrom = $emailclientes

$EmailTo = "email_to_address"

$Subject = "Relatorio Mensal Cliente - $_" 

$Body = "#set attribute A EMPRESA=$_
Gerar relatório referente ao mês $lastmonth/$year" 

$SMTPMessage = New-Object System.Net.Mail.MailMessage($EmailFrom,$EmailTo,$Subject,$Body)
$SMTPClient.Send($SMTPMessage)


}

$SMTPServer = "server.address" 
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 25) 
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("credencial", "password"); 

I Believe that loop doesn’t work correctly.

Thanks for your help.

Rodrigo.

IN brief:

$emailcli = @($clientes, $emailClientes)

What you’ve done here is make a two element array. When you pipe this into your loop, it will pass the first thing, and then the second thing. It’s not going to pass pairs of objects as it seems you are expecting.

To get this kind of behaviour, you need arrays structured in pairs instead.

Hi Joe, Thanks for your reply,

The correct arrays is:

#****************emails from Customers******************************
$emailClientes = @('user1@dom.com';'user2@dom.com','user3@dom.com','user4@dom.com')

#*****************Company names*************************************
$clientes = @('company01','company02','company03','company04')


$emailcli = @($clientes, $emailClientes)

The correlation is user1 to campany1 and etc…

I will use this to create ThroubleTickets into Ticket system by the e-mail. The TO email address is every the same (suporte@xxx.com) and the FROM email must be (I would like to) user (customer) from company.

Did I make understand-me?

Thank you so much.

Why not just use the native powershell command send-mailmessage?

Hi David,

I am using it. But I need to send each email with specific information about each customer.

Thanks for your reply.

Regards,

rc.

I understand, but PS will not. It will pass the first array as a whole object to the next command, then the second array as a whole. It won’t pair-assign individual items in this fashion.

You’ll need to manually step through the arrays and pair your objects, so you have an array that looks like this:

$NewArray = @(
    @('cust1', 'email1')
    @('cust2', 'email2')
)

or you may want to use an array of hashtables instead:

$Customers = @(
    @{Name = 'Customer1'; Email = 'cust@dom.com'}
    @{Name = 'Customer2'; Email = 'cust2@dom.com'}
)

Then as you’re looping through you can reference each .Name and .Email property as you go.

Hi Joe,

Thank you so much foe your reply. The script is almost OK.

See below how the emails came to my mailbox:

The first loop run:


email from: user@company1.com
Subject: Relatorio Mensal - company1


Second loop run:


email from: user@company2.com
Subject: Relatorio Mensal - company1 Company2


Third loop run


email from: user@company3.com
Subject: Relatorio Mensal - company1 Company2 Company3


fourth loop run


email from: email from: user@company4.com
Subject: Relatorio Mensal - company1 Company2 Company3 Company4

the code is below:

[string]$subject = "Relatorio Mensal - "

$lastmonth = (Get-Date).AddMonths(-1).ToString('MMMM')
$year = (get-date).Year

$lastmonth = (Get-Culture).TextInfo.ToTitleCase($lastmonth)



$Customers = @(
    @{Name = 'company1'; Email = 'user@company1.com'}
    @{Name = 'Company2'; Email = 'user@company2.com'}
    @{Name = 'Company3'; Email = 'user@company3.com'}
    @{Name = 'Company4'; Email = 'user@company4.com'}
)|foreach{


$EmailFrom = $_.Email

$EmailTo = "xxxx@.yyy.com"

$Subject = $subject,$_.Name
$_.Name = $null

$Body = "Gerar relatório referente ao mês $lastmonth/$year" 


$SMTPMessage = New-Object System.Net.Mail.MailMessage($EmailFrom,$EmailTo,$Subject,$Body)


$SMTPClient.Send($SMTPMessage)


}

Hmm. Try this in place of the loop and customer definition you have. :slight_smile:

$Customers = @(
    @{Name = 'company1'; Email = 'user@company1.com'}
    @{Name = 'Company2'; Email = 'user@company2.com'}
    @{Name = 'Company3'; Email = 'user@company3.com'}
    @{Name = 'Company4'; Email = 'user@company4.com'}
)

$Customers | ForEach-Object {
    $EmailFrom = $_.Email
    $EmailTo = "xxxx@.yyy.com"
    $Subject = $subject + $_.Name
    $Body = "Gerar relatório referente ao mês $lastmonth/$year" 
    $SMTPMessage = New-Object System.Net.Mail.MailMessage($EmailFrom,$EmailTo,$Subject,$Body)
    $SMTPClient.Send($SMTPMessage)
}

You should be able to specify the same things with Send-MailMessage as you are at the moment. It does make it a tad easier to work with from the cmdlet side as opposed to the .NET side. :slight_smile:

Same behavior.

I guess that $_.Name is no clearing variable.

:-/

Thank you for your reply.

rc.

No, that variable definitely should be clearing.

Ah, found it. You need to call .Dispose() on the object after each message is sent so that you can create it again cleanly… and there’s some other weirdness here, too. This is basically what your loop should look like…

So that portion of the loop should look like:

$Customers = @(
    @{Name = 'company1'; Email = 'user@company1.com'}
    @{Name = 'Company2'; Email = 'user@company2.com'}
    @{Name = 'Company3'; Email = 'user@company3.com'}
    @{Name = 'Company4'; Email = 'user@company4.com'}
)

$SMTPClient = New-Object Net.Mail.SmtpClient("server.address" , 25) 
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("credencial", "password"); 

$Customers | ForEach-Object {
    $EmailFrom = $_.Email
    $EmailTo = "xxxx@.yyy.com"
    $Subject = $subject + $_.Name
    $Body = "Gerar relatório referente ao mês $lastmonth/$year" 
    $SMTPMessage = New-Object System.Net.Mail.MailMessage($EmailFrom,$EmailTo,$Subject,$Body)
    $SMTPClient.Send($SMTPMessage)
    $SMTPMessage.Dispose()
}

Hi team, that script works fine. Here is the code:

_____ Get the previous month-------
$lastmonth = (Get-Date).AddMonths(-1).ToString('MMMM')
$year = (get-date).Year

$lastmonth = (Get-Culture).TextInfo.ToTitleCase($lastmonth)
-----------------------

-------Customers and Company array------------------
$Customers = @(
    @{Name = 'Company01'; Email = 'user@company01.com'}
    @{Name = 'Company02'; Email = 'user@company02.com'}
    @{Name = 'Company03'; Email = 'user@company03.com'}
    @{Name = 'Company04'; Email = 'user@company04.com'}
    @{Name = 'Company05'; Email = 'user@company05.com'}
    @{Name = 'Company06'; Email = 'user@company06.com'} 
    @{Name = 'Company07'; Email = 'user@company07.com'}
    @{Name = 'Company08'; Email = 'user@company08.com'}
)

$customers | ForEach-Object{

    $EmailFrom = $_.Email
    $EmailTo = "suporte@mailserver.inf.br"
    
    $Subject = "Subject - " + $_.Name
    
    $Body = "Explanations for the email."
 
    $SMTPMessage = New-Object System.Net.Mail.MailMessage($EmailFrom,$EmailTo,$Subject,$Body)
    $SMTPClient.Send($SMTPMessage)


}

$SMTPServer = "mail.mailserver.inf.br" 
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 25) 
#$SMTPClient.EnableSsl = $true 
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("user@mailserver.inf.br", "xxxxxxx"); 

Thank’s for all help.