none
Envoie de mail en powershell RRS feed

  • Discussion générale

  • Bonjour,

    J'ai besoin d'envoyer des mail automatiquement dans mon script powershell, j'ai donc testé un certain nombre de façon mais à chaque fois ça ce termine de la même façon, j'ai une erreur quand j'active le ssl.

    Ici en passant sur le port 587 avec le ssl désactivé ça marche mais je n'ai pas envie que mon mdp passe en clair.

    $SMTPServer = "smtp.orange.fr"
    $Username = "maboite@orange.fr"
    $From = "maboite@orange.fr"
    $Password = "*****"
    
    $to = "suppinfra@maboite.fr"
    $subject = "sujet"
    $body = "Insert body text here"
    
     #Create the credentials for the smtpauth connection
     $credentials = New-Object System.Net.NetworkCredential($Username, $Password);
     #Create the message
     $message = New-Object System.Net.Mail.MailMessage $From, $to, $subject, $body
     #Add attachment to $message if one exists
    
     # Set up server connection
     $smtpClient = New-Object System.Net.Mail.SmtpClient $SMTPServer, 587
     $smtpClient.EnableSsl = $false
     $smtpClient.Timeout = 100000
     $smtpClient.UseDefaultCredentials = $false;
     $smtpClient.Credentials = $credentials
     #Send the message
     $smtpClient.Send($message)
    # Write-Host "Message sent."

    Sauf que quand je passe sur le port 465 (le port ssl du smtp Orange) avec le ssl activé ou non j'ai cette erreur :

    Exception calling "Send" with "1" argument(s): "Failure sending mail."
    At C:\Suppinfra\test_smtp2.ps1:43 char:2
    +  $smtpClient.Send($message)
    +  ~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
        + FullyQualifiedErrorId : SmtpException

    Tous les exemples utilisant send me sorte cette erreur mais je ne vois vraiment pas quel est le problème. Est ce que vous auriez une idée pour passer ce problème ou au moins le contourner ?

    mardi 11 avril 2017 08:20

Toutes les réponses

  • Un cmdlet existe pour envoyer des mail

    Send-MailMessage

    Inutile de jouer avec l'ancienne méthode!

    B.

    mardi 11 avril 2017 08:48
  • Oui j'ai aussi testé cette cmdlet avec ce code :

    $From = "maboite@orange.fr"
    $To = "suppinfra@maboite.fr"
    $SMTPServer = "smtp.orange.fr"
    $SMTPPort = "465"
    $Username = "toto"
    $subject = "$codeEnErreur à créer ($reference)"
    $body = "Il est nécessaire de créer le $codeEnErreur de référence $reference"
    
    $PWord = ConvertTo-SecureString –String "******" –AsPlainText -Force
    $Credential = New-Object System.Management.Automation.PSCredential ($Username, $PWord)
    
    Send-MailMessage -To $To -From $From -Subject "test" -SmtpServer $SMTPServer -Body $body -Port $SMTPPort -UseSsl -Credential $Credential

    Ça marche aussi sans ssl et sur le port 587, mais avec ça me sort cette erreur :

    Send-MailMessage : Unable to read data from the transport connection: Une connexion existante a dû être fermée par l’hôte distant.
    At C:\test.ps1:34 char:2
    +     Send-MailMessage -To $To -From $From -Subject "test" -SmtpServer  ...
    +     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidOperation: (System.Net.Mail.SmtpClient:SmtpClient) [Send-MailMessage], SmtpException
        + FullyQualifiedErrorId : SmtpException,Microsoft.PowerShell.Commands.SendMailMessage

    Mais peut être que cette erreur vous parlera plus. Est ce que l'ordre des paramètres de send-mailMessage est important ?

    • Modifié l'axiome mardi 11 avril 2017 13:03
    mardi 11 avril 2017 13:01
  • J'ai trouvé ça sur le net pour gmail peut être que tu peux adapter pour voir pour orange

    $From = "YourEmail@gmail.com"
    $To = "AnotherEmail@YourDomain.com"
    $Cc = "YourBoss@YourDomain.com"
    $Attachment = "C:\temp\Some random file.txt"
    $Subject = "Email Subject"
    $Body = "Insert body text here"
    $SMTPServer = "smtp.gmail.com"
    $SMTPPort = "587"
    Send-MailMessage -From $From -to $To -Cc $Cc -Subject $Subject -Body $Body -SmtpServer $SMTPServer -port $SMTPPort -UseSsl -Credential (Get-Credential) -Attachments $Attachment


    Merci de marquer comme réponse les sujets qui vous ont permis d'avancer afin que cela puisse être bénéfique aux personnes qui rencontrent le même problème.


    mardi 11 avril 2017 17:04
  • Tu te trouve derrière une connexion Orange?

    Si oui, il est probable qu'il y ait pas besoin de login/pwd

    Je ne connais pas orange, n'étant pas en france.

    GMail est aussi une autre possibilité

    B.
    mardi 11 avril 2017 18:15
  • Désolé Matteu mais j'ai la même erreur qu'avec le code précédent.

    Sinon oui je suis sur un connexion orange, et mon premier test était justement sans connexion avec ce code:

    $message = 'Il est nécessaire de créer le $codeEnErreur de référence $reference' $emailTo = "suppinfra@maboite.fr" $emailFrom = "suppinfra@maboite.fr" $subject="$codeEnErreur à créer ($reference)" $smtpserver="smtp.orange.fr" Send-MailMessage -To $emailTo -From $emailFrom -subject $subject -Body $message -SmtpServer $smtpserve

    Mais il me demande une authentification

    Send-MailMessage : Mailbox unavailable. The server response was: 5.1.0 Authentification requise. Authentication Required. OFR102_402 [402]
    At C:\Suppinfra\test_fichier.ps1:22 char:1
    + Send-MailMessage -To $emailTo -From $emailFrom -subject $subject -Bod ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidOperation: (System.Net.Mail.SmtpClient:SmtpClient) [Send-MailMessage], SmtpException
        + FullyQualifiedErrorId : SmtpException,Microsoft.PowerShell.Commands.SendMailMessage

    Et autrement j'ai testé en Python et ça marche sans problème en ssl, donc pas de soucis de pare feu qui bloquerais un truc ou de mdp faux.


    • Modifié l'axiome mercredi 12 avril 2017 08:33
    mercredi 12 avril 2017 08:30
  • Bonjour,

    La méthode est bonne, et vous avez fait ce qu'il fallait, le problème vient plutôt du serveur SMTP qui ne supporte pas le TLS. Pour info le SMTPS  sur le port 465 est un protocole déprécie depuis 1998, même si certains continuent de l'implémenter : https://en.wikipedia.org/wiki/SMTPS

    Voici le resultat d'un telnet smtp.orange.fr 587, normalement il devrait me répondre un 250 - STARTTLS en plus si il acceptait le chiffrement.

    220 mwinf5d81 ME ESMTP server ready
    EHLO localhost
    250-mwinf5d81 hello [78.236.52.136], pleased to meet you
    250-HELP
    250-AUTH LOGIN PLAIN
    250-SIZE 44000000
    250-ENHANCEDSTATUSCODES
    250-8BITMIME
    250 OK
    quit
    221 2.0.0 mwinf5d81 ME closing connection


    Bruce Jourdain de Coutance - Consultant MVP Exchange http://blog.brucejdc.fr


    • Modifié Bruce JDC mercredi 12 avril 2017 18:32
    mercredi 12 avril 2017 18:31
  • salut l'axiome

    tu trouvera sur ce site la solution pour te connecté au smtp d'orange en "Implicit SSL"

    comme dis Bruce JDC orange utilise un ancien protocol

    mais send-mailmessage semble aussi être obsolète d'après un test sur gmail qui le considère comme "Application moins sécurisée"

    je te copie la version préparé pour orange :

    # Mail Message
    $from = "ton_mail@orange.fr"
    $to = "ton_mail@orange.fr"
    $subject = "Hello from PowerShell"
    $body = "This is a message saying hello from PowerShell."
    $hasAttachment = $false
    $attachmentPath = "attachmentPath.txt"
    $Username = "ton_mail@orange.fr"
    $mdp = "ton_password"
    
    
    # Mail Server Settings
    $server = "smtp.orange.fr"
    $serverPort = 465
    $timeout = 30000          # timeout in milliseconds
    $enableSSL = $true
    $implicitSSL = $true
    
    # Get user credentials if required
    if ($enableSSL) {
        #$credentials = [Net.NetworkCredential](Get-Credential)
        $credentials = New-Object System.Net.NetworkCredential($Username, $mdp) 
        }
    
    if (!$enableSSL -or !$implicitSSL) {
        # Set up server connection
        $smtpClient = New-Object System.Net.Mail.SmtpClient $server, $serverPort
        $smtpClient.EnableSsl = $enableSSL
        $smtpClient.Timeout = $timeout
    
        if ($enableSSL) {
            $smtpClient.UseDefaultCredentials = $false;
            $smtpClient.Credentials = $credentials
            }
    
        # Create mail message
        $message = New-Object System.Net.Mail.MailMessage $from, $to, $subject, $body
    
        if ($hasAttachment) {
            $attachment = New-Object System.Net.Mail.Attachment $attachmentPath
            $message.Attachments.Add($attachment)
            }
    
        # Send the message
        Write-Output "Sending email to $to..."
        try {
            $smtpClient.Send($message)
            Write-Output "Message sent."
            }
        catch {
            Write-Error $_
            Write-Output "Message send failed."
            }
        }
    else {
        # Load System.Web assembly
        [System.Reflection.Assembly]::LoadWithPartialName("System.Web") > $null
    
        # Create a new mail with the appropriate server settigns
        $mail = New-Object System.Web.Mail.MailMessage
        $mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpserver", $server)
        $mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpserverport", $serverPort)
        $mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpusessl", $true)
        $mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendusername", $credentials.UserName)
        $mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendpassword", $credentials.Password)
        $mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout", $timeout / 1000)
        # Use network SMTP server...
        $mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendusing", 2)
        # ... and basic authentication
        $mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", 1)
    
        # Set up the mail message fields
        $mail.From = $from
        $mail.To = $to
        $mail.Subject = $subject
        $mail.Body = $body
    
        if ($hasAttachment) {
            # Convert to full path and attach file to message
            $attachmentPath = (get-item $attachmentPath).FullName
            $attachment = New-Object System.Web.Mail.MailAttachment $attachmentPath
            $mail.Attachments.Add($attachment) > $null
            }
    
        # Send the message
        Write-Output "Sending email to $to..."
        try {
            [System.Web.Mail.SmtpMail]::Send($mail)
            Write-Output "Message sent."
            }
        catch {
            Write-Error $_
            Write-Output "Message send failed."
            }
        }
    

    jeudi 13 avril 2017 08:50
  • Salut,

    un ajout :

    try {  
     [System.Web.Mail.SmtpMail]::Send($mail)
     Write-Output "Message sent."
    } catch {  
     Write-Error $_  
     Write-Output "Message send failed."
    } finally { $mail.Dispose() }



    Beatus, qui prodest, quibus potest.

    jeudi 13 avril 2017 10:58
    Modérateur
  • merci Laurent pour la liberation de la resource, absente du script d'origine :)

    Ici en passant sur le port 587 avec le ssl désactivé ça marche mais je n'ai pas envie que mon mdp passe en clair.

    j'ai refait quelque test avec Send-MailMessage et il fonctionne avec Orange sur le port 587 et sans ssl Mais le mdp est crypté sur le réseau :

    $From = "ton_mail@orange.fr"
    $To = "ton_mail@orange.fr"
    $SMTPServer = "smtp.orange.fr"
    $SMTPPort = 587
    $Username = "ton_mail@orange.fr"
    $subject = "test envoie"
    $body = "message d erreur"
    
    $mdp = "ton_password"
    $PWord = ConvertTo-SecureString –String $mdp –AsPlainText -Force
    $Credential = New-Object System.Management.Automation.PSCredential ($Username, $PWord)
    Send-MailMessage -To $To -From $From -Subject $subject -SmtpServer $SMTPServer -Body $body -Credential $Credential  -Port $SMTPPort 

    je viens de faire une trace avec wireshack, le login et le password sont bien crypté

    si tu a besoin que le mot de passe ne soit pas lisible dans le script fait nous le savoir ;)




    • Modifié 6ratgus mardi 18 avril 2017 14:47
    jeudi 13 avril 2017 15:42
  • Je vais tester ça mais déjà un grand merci pour votre aide !
    mardi 18 avril 2017 07:43
  • Ça fonctionne, par contre excusez mes erreurs de débutant mais lorsque j'ajoute la méthode dispose j'ai l'erreur suivante

    Method invocation failed because [System.Web.Mail.MailMessage] does not contain a method named 'Dispose'.
    At C:\Suppinfra\MEILLER\itus_dev\test.ps1:97 char:21
    +             }finally { $mail.Dispose() }
    +                        ~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
        + FullyQualifiedErrorId : MethodNotFound

    Apparemment Dispose() serai une méthode spécifique à System.net.Mail, du coup je ne sais pas si je dois importer quelque chose de spécifique ou chercher un équivalent à cette méthode avec system.web.mail.
    A moins que les ressources soient re-alloué automatiquement avec web.mail ? (rendant dispose() inutile).

    mardi 18 avril 2017 13:24
  • Oui, une erreur de ma part sur le nom de classe, System.Web.Mail.MailMessage n'implémente pas l'interface IDisposable. J'ai l'habitude d'utiliser System.Net.Mail.MailMessage.

    Soit tu adaptes le code, System.Web.Mail.MailMessage étant Obsolète, soit tu l'utilises en l'état en supprimant la clause Finally.


    Beatus, qui prodest, quibus potest.

    mardi 18 avril 2017 14:14
    Modérateur
  • Ok alors j'enlève Finally{}, merci.
    mardi 18 avril 2017 14:35
  • Bonjour, 

    Je déterre un peu le sujet mais ce script m'intéresse beaucoup et fonctionne très bien. Par contre je serai intéressé par le fait que le mot de passe ne soit pas lisible dans le script.

    Merci par avance.

    Alexis

    mercredi 27 septembre 2017 14:49
  • Bonjour

    Vous pouvez stocker le mot de passe de façon securisé dans un fichier et le lire ensuite dans votre script

    #Pour ecrire le mdp dans un fichier
    read-host -assecurestring | convertfrom-securestring | out-file C:\cred.txt 
    
    #Pour le lire et le réutiliser
    $pass = cat C:\cred.txt | convertto-securestring

    https://blogs.technet.microsoft.com/robcost/2008/05/01/powershell-tip-storing-and-using-password-credentials/


    jeudi 28 septembre 2017 14:12