Buscar

Script para automatizar el envío de un mail con PowerShell

Con PowerShell podemos automatizar el envío de un correo electrónico con el cmd-let Send-MailMessage.

  

Podemos encontrar este cmd-let a partir de la versión 2 de PowerShell.

A continuación podemos ver un script de PowerShell a modo de ejemplo.

En este ejemplo se envía el contenido del fichero Contenido-Mail.txt al SMTP server 192.168.1.250.

El from del correo será usuario1@empresa.com y los destinatarios usuario2@empresa.com, usuario3@empresa.com



$file = "Contenido-Mail.txt"

if (test-path $file)
{

    $from = "usuario1@empresa.com"
    $to = "usuario2@empresa.com","usuario3@empresa.com"

    #Las direcciones del to deben indicarse con signos de mayor que 
    #y menor que.
    $pc = get-content env:computername
    $subject = "Mesaje de prueba del servidor " + $pc
    $smtpserver = "192.168.1.250"


    #Con Out-String formateamos el texto
    $body = Get-Content $file | Out-String


    foreach ($recipient in $to)
    {
        write-host "Enviando mail a $to"
        Send-MailMessage -smtpServer $smtpserver -from $from -to $recipient -subject $subject  -body $body
    }
}
else
{
write-host "Fichero no encontrado"
}

29 comentarios:

  1. Hola gracias por tu publicacion pero tengo una duda porque me sale un error en la primera linea:

    -- La siguiente linea tengo que colocarle la ruta donde se encuentra el archivo que voy a enviar o significa otra cosa:
    $file = "Contenido-Mail.txt"
    if (test-path $file)

    ResponderEliminar
  2. Hola John, ¡gracias por tu comentario!

    El fichero Contenido-Mail.txt es un fichero de texto que contiene el cuerpo del mensaje (el body) que quieres enviar. Puede estar el fichero en blanco, pero ha de estar creado.

    Si no indicas ninguna ruta (como en el ejemplo del post) por defecto el script irá a buscar el fichero Contenido-Mail.txt en la misma carpeta donde esté situado el script de PowerShell (.PS1)

    ¡Espero haberte ayudado!

    ResponderEliminar
  3. Gracias Xavi, ya me funciono. Ahora me gustaria automatizar el envio con el programador de tarea pero no me ejecuta el script. Existe alguna forma de hacerlo por ahi o que otra forma me recomienda.

    ResponderEliminar
  4. Puedes llamar un script de PowerShell desde el programador de tareas de la siguiente forma:

    1) Creas un bat (mailsend.bat) con el siguiente contenido:

    powershell -file nombre-script-de-powershell.ps1

    2) Sitúas el bat en la misma carpeta donde está el fichero .ps1

    3) Creas la tarea programada llamando al bat: recuerda configurar el directorio donde está situado el bat en la opción "Iniciar en (opcional)".

    ResponderEliminar
  5. Hola, me pueden indicar porque me sale este error?

    ResponderEliminar
  6. Disculpa me sale este error.

    Send-MailMessage : El servidor SMTP requiere una conexión segura o el cliente no se autenticó. La respuesta del servidor fue: 5.7.0 Must issue a STARTTLS command first. o61sm2625648y
    hp.5 - gsmtp
    En C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\Backup\enviar un archivo con power shell.ps1: 22 Carácter: 25
    + Send-MailMessage <<<< -smtpServer $smtpserver -from $from -to $recipient -subject $subject -body $body
    + CategoryInfo : InvalidOperation: (System.Net.Mail.SmtpClient:SmtpClient) [Send-MailMessage], SmtpException
    + FullyQualifiedErrorId : SmtpException,Microsoft.PowerShell.Commands.SendMailMessage

    ResponderEliminar
    Respuestas
    1. Creo que el problema es que tu servidor SMTP requiere SSL para realizar la autenticación de usuario y password.

      Por ejemplo, si indicas el SMTP de GMail, requiere SSL.

      Te aconsejaría que o bien indiques un servidor externo SMTP sin SSL o bien indiques un servidor SMTP interno donde tu puedes controlar si requiere o no SSL.

      Un saludo y gracias por participar en el blog!

      Eliminar
    2. Hola a mi me funciono esto para usar ssl y autenticar en gmail

      $SMTPServer = "smtp.gmail.com"
      $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
      $SMTPClient.EnableSsl = $true
      $SMTPClient.Credentials = New-Object System.Net.NetworkCredential(“usuario@dominio.com”, “password”);

      Eliminar
  7. pero yo no veo donde colocar el user y pass. me puedes ayudar?

    ResponderEliminar
    Respuestas
    1. El Script no permite pasar la autenticación. El servidor SMTP externo o interno debe permitir la salida desde la IP origen desde donde se ejecuta el Script. Solo que tengas un servidor SMTP en tu red que puedas configurar, ya te valdría.

      Eliminar
  8. Hola Xavi, antes de nada felicitarte por tu blog y tus libros...casi has plasmado lo buen profesor que eres en tus libros ;)

    #####Con este script puedes enviar a los correos internos de tu exchange ########
    #####Pide y guarda las credenciales en un archivo dominio\usuario y password#####

    $cred = Get-Credential

    $cred | Export-CliXml c:\temp\cred.clixml

    $cred2 = Import-CliXml c:\temp\cred.clixml

    Send-MailMessage -From "usuario@dominio.com" -to "usuario@dominio.com" -Subject "hello" -SmtpServer "url owa" -Credential $cred2


    Saludos

    ResponderEliminar
    Respuestas
    1. ¡¡Muchas gracias Rubén!! Un abrazo!!

      Eliminar
    2. Qué tal Rubén, por lo que estoy viendo la función Get-Credential hace que se abra una ventana para ingresar usuario y contraseña, hay manera de pasarle usuario y contraseña en el mismo script, ya que lo voy a ejecutar como tarea programada. Saludos!

      Eliminar
  9. Yo no soy capaz de hacer el script para que me envie un mail cada vez que se enciende el pc. 😢😢

    ResponderEliminar
    Respuestas
    1. Hola Jose Ignacio,

      Puedes programar la ejecución de un script con Powershell con una tarea programada.

      Programador de tareas > Crear tarea > pestaña desencadenadores > Nuevo > Iniciar tarea: > Seleccionar al iniciar el sistema o bien al iniciar sesión.

      Eliminar
  10. Gracias Xavi por tu respuesta. Pero no puedo/se crear un Powershell.

    ResponderEliminar
    Respuestas
    1. Para iniciarte con la PowerShell, te recomiendo que antes de nada leas el apartado del libro "FAQ - PowerShell" del libro "WS2012LABS - Windows Server 2012"

      Eliminar
  11. Xavi,

    Muchas gracias por tu POst! esta genial, pero me puedes ayudar? tengo este error:

    Send-MailMessage : Cannot validate argument on parameter 'Body'. The argument is null or empty. Supply an arg
    is not null or empty and then try the command again.
    At C:\Scripts\Script.ps1:22 char:101
    + Send-MailMessage -smtpServer $smtpserver -from $from -to $recipient -subject $subject -body <<<<
    + CategoryInfo : InvalidData: (:) [Send-MailMessage], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.SendMailMessage


    Saludos

    ResponderEliminar
  12. Hola Xavier,

    Muchas gracias por el post!

    Me ha funcionado de maravilla, solo que tengo una duda, yo voy estar generando ese archivo cada dia, sabes como debo hacer para que el script al ejecutarse con la tarea programada del bat, tome el archivo del dia? que sería el ultimo generado y no otro?

    Saludos

    ResponderEliminar
    Respuestas
    1. Solo que situes el fichero TXT en el mismo fichero que el script, te funcionará.

      Si quieres que el script se ejecute de forma programada, utiliza una tarea programada:

      Puedes utilizar este ejemplo:

      http://www.sysadmit.com/2015/06/vmware-powercli-tarea-programada.html

      Al no ser un script de PowerCLI (PowerShell de VMware), no incluyas lo siguiente en su interior:

      Add-PSSnapin VMware.VimAutomation.Core

      Connect-VIServer -Server XXX.XXX.XXX.XXX -User YYYYYYY -Password ZZZZZZZZ

      Eliminar
  13. me sale error : no es posible conectar con el servidor remoto

    ResponderEliminar
  14. si quiero enviar un adjunto como hago

    ResponderEliminar
    Respuestas
    1. Hola,

      El cmd-let: Send-MailMessage, dispone del parámetro "Attachments", donde puedes especificar la ruta completa del fichero a adjuntar.

      Ejemplo:

      -Attachments “C:\SYSADMIT\fichero.docx”

      Un saludo,

      Xavi.

      Eliminar
  15. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  16. Hola,

    Alguien podría ayudarme con una cuestión? Haciendo el script, me he dado cuenta que sería mucho más sencillo para mí poder añadir el mail del destinatario a mano cada vez que se ejecuta el script, es decir poder introducir los datos una vez ejecutado y no dentro del código. En la función:
    $to = "usuario2@empresa.com","usuario3@empresa.com"
    Cómo podría ser esto posible?
    Tengo entendido que con un pause se podría hacer.
    Gracias.

    ResponderEliminar
  17. Hola buenas, tengo programados envíos de correo al finalizar backups y otros procesos, de una cuenta exclusiva para reportes a la cuenta de correo del trabajo, pero outlook me ha bloqueado la cuenta de reportes. ¿Hay algún servicio que permita esto sin detectarlo como un proceso malintencionado?

    ResponderEliminar
    Respuestas
    1. Hola Kevin,

      Deberías verificar si el sistema de correo electrónico que bloquea los correos te permite configurar los correos de los reportes de backup, etc.. en lista blanca.

      Gracias,

      Xavi.

      Eliminar
  18. ¿Es posible pasar una variable para que el nombre del remitente sea diferente?
    Por ejemplo: declarar $from:"ejemplo@dominio.com" como remitente original y despues con algun otro parametro cambiarlo para que se muestre en el mensaje como "ejemplo2@dominio2.com

    ResponderEliminar