Búsqueda de sitios web

Send-MailMessage: envío de correos electrónicos con PowerShell


Puede usar el cmdlet Send-MailMessage integrado para enviar correos electrónicos SMTP desde PowerShell. Puede usar este cmdlet para enviar correos electrónicos en PowerShell versión 2.0 y posteriores (anteriormente podía usar .Net

System.Net.Mail

clase para enviar mensajes de correo electrónico). Send-MailMessage le permite enviar mensajes con archivos adjuntos, usar formato HTML para el cuerpo del mensaje, habilitar la notificación de entrega, enviar un mensaje a varios destinatarios a la vez, etc. En este artículo, veremos cómo usar el

Send-MailMessage

cmdlet para enviar mensajes de correo electrónico desde sus scripts de PowerShell.

Cmdlet PowerShell Send-MailMessage: parámetros y ejemplos

Para obtener la sintaxis del cmdlet, ejecute este comando:

get-help Send-MailMessage
Send-MailMessage [-To] <String[]> [-Subject] <String> [[-Body] <String>] [[-SmtpServer] <String>] [-Attachments <String[]>] [-Bcc <String[]>] [-BodyAsHtml] [-Cc <String[]>] [-Credential <PSCredential>] [-DeliveryNotificationOption {None | OnSuccess | OnFailure | Delay | Never}] [-Encoding <Encoding>] -From <String> [-Port <Int32>] [-Priority {Normal | Low | High}] [-UseSsl] [<CommonParameters>]
The Send-MailMessage cmdlet sends an email message from within Windows PowerShell.

Estas son las principales opciones:

  • De: es una dirección de remitente. Puede enviar un mensaje de correo electrónico en nombre de cualquier dirección de correo electrónico si el servidor SMTP no verifica la dirección del remitente (retransmisión anónima);

  • Para: la dirección de correo electrónico del destinatario;

  • Servidor SMTP: la dirección del servidor SMTP a través del cual desea enviar el correo electrónico.

La dirección del servidor SMTP no es necesaria si configura la dirección del servidor de correo en la variable de entorno $PSEmailServer:

$PSEmailServer = "smtp.a-d.site"

El siguiente comando de PowerShell enviará un correo electrónico con el asunto y el cuerpo especificados a varios destinatarios.

Send-MailMessage -From 'ps-script@a-d.site' -To 'serveradmin@a-d.site','helpdesk@a-d.site' -Subject "Test Email Alert" -Body "This is email body text" -SmtpServer 'smtp.a-d.site'

Puede enviar un correo electrónico a uno o más buzones de destinatarios, a un canal de Teams o a una dirección en un grupo de distribución de Exchange.

Para facilitar la edición de los atributos de un cmdlet, el comando Send-MailMessage se puede representar de la siguiente manera:

Send-MailMessage `
-SmtpServer smtp.a-d.site `
-To 'serveradmin@a-d.site','helpdesk@a-d.site' `
-From 'ps-script@a-d.site' `
-Subject "Test" `
-Body "Sending email using PowerShell" `
-Encoding 'UTF8'

Tenga en cuenta que en el último comando, configuramos adicionalmente la codificación UTF8 para el correo electrónico. De lo contrario, si el asunto o el cuerpo del correo electrónico contiene caracteres que no son ANSI, se mostrarán incorrectamente.

Windows PowerShell usa la codificación ANSI y ASCII de forma predeterminada. Si ha actualizado su versión de PS a PowerShell Core, tenga en cuenta que esta versión ya utiliza la codificación UTF-8 de forma predeterminada.

Puede especificar varios destinatarios utilizando los parámetros:

  • To

    - las direcciones de correo electrónico del destinatario habitual;

  • Cc

    - las direcciones de correo electrónico para enviar una copia al carbón (CC) del mensaje de correo electrónico;

  • Bcc

    - las direcciones de correo electrónico que recibirán una copia del correo electrónico pero que no aparecerán como destinatarios del mensaje.

Puede habilitar una notificación de entrega para un correo electrónico usando -DeliveryNotificationOptions (que le permite recibir una notificación cuando el destinatario recibe un correo electrónico). Los tipos de notificación disponibles son:

  • OnSuccess(Notificar si la entrega es exitosa)

  • OnFailure(Notificar si la entrega no se realiza correctamente)

  • Retraso(Notificar si la entrega se retrasa)

Puede especificar múltiples opciones en un comando:

Send-MailMessage … -DeliveryNotificationsOptions 'OnSuccess', 'OnFailure'

La notificación de entrega se enviará al buzón que se especifica en el campo "De".

También puede establecer la prioridad del mensaje de correo electrónico (no se muestra en algunos clientes):

-Priority High|Low|Normal

Si desea agregar un archivo adjunto a su correo electrónico, use la opción -Archivos adjuntos. En el siguiente ejemplo, enviaremos un correo electrónico en formato HTML (-BodyAsHtml) y adjuntaremos file1.txt y report.xsls desde el disco local.

$MailMessage = @{
To = "admin@a-d.site"
Bcc = "manager@a-d.site", "manager2@a-d.site"
From = "DC server <dc01@a-d.site>"
Subject = "DC Server Report"
Body = "<h1>Welcome!</h1> <p><strong>Generated:</strong> $(Get-Date -Format g)</p>”
Smtpserver = "smtp.gmail.com"
Port = 587
UseSsl = $true
BodyAsHtml = $true
Encoding = “UTF8”
Attachment = “C:\Logs\file1.txt”, “C:\Logs\report.xlsx”
}
Send-MailMessage @MailMessage -Credential $cred

En este ejemplo, también reemplazamos el nombre para mostrar del destinatario con "servidor DC".

Así es como se ve el correo electrónico HTML con archivos adjuntos en la interfaz de Gmail.

Cuando envía un correo electrónico en nombre de un buzón de correo compartido de Exchange/Microsoft 365 para el que se le han otorgado permisos SendAs, puede especificar que se guarde una copia del mensaje en la carpeta Elementos enviados del buzón de origen. Para eso, habilite el parámetro MessageCopyForSentAsEnabled para el buzón:

Set-Mailbox it_dept -MessageCopyForSentAsEnabled $True

Uso de Send-MailMessage con SMTP Auth y TLS/SSL

De forma predeterminada, el cmdlet Send-MailMessage envía un correo electrónico a través del puerto SMTP predeterminado TCP 25 sin cifrar. Si su servidor SMTP permite enviar correos electrónicos solo mediante un protocolo cifrado, puede especificar el número de puerto en el atributo -Port (la mayoría de las veces es 465 o 587) y la opción -UseSsl:

-SmtpServer 'smtp.a-d.site' -Port 465 -UseSsl

Se producirá un error si el certificado SSL del servidor SMTP no coincide con el FQDN especificado en HELO:

Send-MailMessage: The remote certificate is invalid according to the validation procedure.

También puede recibir un error al enviar un correo electrónico utilizando el cifrado SSL/TLS:

Send-MailMessage : Unable to read data from the transport connection: net_io_connectionclosed

En este caso, se recomienda que compruebe lo siguiente

  • Que el puerto SMTP especificado esté abierto y accesible desde su computadora:

    Test-NetConnection smtp.a-d.site -Port 465
  • Pruebe con un puerto SMTP diferente. Por ejemplo, 587 (msa) en lugar de 465 (smtps). El puerto 587 es el predeterminado cuando se usa la extensión STARTTLS;

  • Si está utilizando un sistema operativo anterior (Windows Server 2012/Windows 8 e inferior), debe habilitar la compatibilidad con el protocolo TLS 1.2 para PowerShell mediante el comando:

    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

La siguiente tabla enumera la configuración del servidor SMTP para los proveedores de correo electrónico público populares que puede usar para enviar mensajes desde PowerShell (tenga en cuenta que debe permitir que el correo electrónico se envíe a través de SMTP en la interfaz de la cuenta):

NameSMTP Server AddressPortEncryption Type
Gmailsmtp.gmail.com587

25

465

TLS

TLS

SSL

Microsoft (Office) 365smtp.office365.com587TLS
Outlook.comsmtp-mail.outlook.com587TLS
Yahoosmtp.mail.yahoo.com587TLS
iCloud mailsmtp.mail.me.com587TLS
AOL smtp.aol.com465SSL

Si el servidor SMTP no permite el correo electrónico anónimo (se deniega la retransmisión), verá este error:

5.7.1 Client was not authenticated.

o :

The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.57 SMTP; Client was not authenticated to send anonymous mail during MAIL FROM.

Luego puede autenticarse en el servidor SMTP usando la opción -Credential.

Puede solicitar de forma interactiva las credenciales del usuario para la autenticación:

Send-MailMessage …… -Credential (Get-Credential)

También puede especificar las credenciales de la cuenta que se usarán para la autenticación en la variable:

$cred = Get-Credential
Send-MailMessage ... -Credential $cred

¿Cómo enviar un correo electrónico a través de Gmail SMTP con PowerShell?

Para enviar un correo electrónico desde su buzón en uno de los servicios públicos de correo, se recomienda que utilice una contraseña de aplicación en lugar de una contraseña para acceder a su cuenta/buzón. Por ejemplo, en Gmail, puede crear una contraseña de aplicación después de habilitar la autenticación de dos factores para su cuenta de Google. Genere y copie la contraseña de su aplicación en Google (es una contraseña de 16 caracteres).

El siguiente ejemplo muestra cómo enviar un correo electrónico desde su buzón de Google usando PowerShell. Debe utilizar la contraseña de la aplicación en lugar de la contraseña de su cuenta de Google. En este ejemplo, especificaremos la contraseña de la aplicación para conectarse al servidor SMTP de Gmail directamente en el código del script de PowerShell.

$From = "sender@gmail.com"
$To = "recipient@gmail.com"
$Subject = "Test PowerShell email from $($env:computername)"
$Body = "some message test "
$Password = "your_google_app_password" | ConvertTo-SecureString -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $From, $Password
Send-MailMessage -From $From -To $To -Subject $Subject -Body $Body -SmtpServer "smtp.gmail.com" -port 587 -UseSsl -Credential $Credential

Tenga en cuenta que PowerShell guarda el comando con la contraseña de texto sin formato en el archivo de historial de comandos de PowerShell. Lea el artículo sobre cómo usar y proteger las contraseñas en los scripts de PowerShell.

Se muestra una advertencia cuando usa el comando Send-MailMessage en nuevas versiones de PowerShell Core 7.x:

WARNING: The command 'Send-MailMessage' is obsolete. This cmdlet does not guarantee secure connections to SMTP servers. While there is no immediate replacement available in PowerShell, we recommend you do not use Send-MailMessage at this time. See https://aka.ms/SendMailMessage for more information.

El cmdlet Send-MailMessage usa la clase .NET SmtpClient que no admite métodos de autenticación modernos, incluida la autenticación moderna de Microsoft. Se recomienda que use Graph API para enviar correos electrónicos desde PowerShell a través de Microsoft 365/Exchange Online (usando el

Send-MgUserMail

cmdlet o

Invoke-RestMethod

para llamar al método sendMail a través de la API REST).

Artículos relacionados