[TIP] Enviar correos directamente desde POWERSHELL

Colapsar
X
 
  • Filtrar
  • Tiempo
  • Mostrar
Limpiar Todo
nuevos mensajes
  • jmtella
    Administrator
    • Nov
    • 20580

    [TIP] Enviar correos directamente desde POWERSHELL

    Hace unos días me surgió la necesidad de enviar correos de una forma rápida desde una maquina de la red local cuando se enciende. Enviarlos de una manera sencilla, sin tener instalado nada de correo y que me comunicase su hora de conexión, nombre de maquina y la IP que tiene la maquina en ese momento. La solución es sencilla, un script de powershell lo permite.

    Os dejo un ejemplo de esto, enviado usando una cuenta de gmail, que es lo que aconsejo, ya que gmail permite estos reenvíos directamente. EL problema es que gmail usa seguridad, por lo cual voy a dejar abajo el script completo, incluso enviando un adjunto que lo realiza.

    Igualmente necesitamos poner la password de gmail, y esto no me gusta dejarlo en un script, por lo cual se debe dejar en un fichero encriptado. Para ello, y suponiendo que vamos a dejar los scripts en la carpeta c:\util\ps (cambiarlo si es necesario), lo primero que ejecutamos en un powrshell es:

    Código:
    "tu password gmail" | Convertto-SecureString -AsPlainText -Force | ConvertFrom-SecureString | Out-file "c:\util\ps\pw-ccif1.txt"
    Poner en 'tu password gmail' la password de vuestra cuenta de gmail. Esto dejará encriptada la password en el fichero c:\util\ps\pw-ccif.txt (podeis entrar a mirarlo, y ver lo que ha dejado). La encriptacion es "por maquina", es decir hay que ejecutarlo en las maquinas que queramos usar el script y no copiarlo desde otra maquina. Solo, evidentemente hay que hacerlo una vez.

    El script para envío, es:

    Código:
    <#
    Previamente: (hacerlo por fuera una sola vez por maquina)
    
        "tu password" | Convertto-SecureString -AsPlainText -Force | ConvertFrom-SecureString | Out-file "c:\util\ps\pw-ccif1.txt"
    
    Ejecutar como:
    
        powershell -executionpolicy remotesigned -File C:\util\ps\correops.ps1
    
    #>
    $scriptpath = $MyInvocation.MyCommand.Path
    $dir = Split-Path $scriptpath
    #
    $EmailPropio = "tucuentadegmail@gmail.com";
    $EmailDestino = "cuentadestinocorreo@loquesea.com";
    #
    $Asunto = "Conexion: $env:computername $((Get-Date).ToString())"
    $Texto = "Conectado desde $env:computername a las $((Get-Date).ToString())"
    #
    $ServidorSMTP = "smtp.gmail.com"
    $Archivo = "$dir\ipps.txt"
    Get-NetIPAddress -AddressFamily ipv4 | ft IPAddress, InterfaceAlias | out-file -filepath $Archivo
    $Adjunto = New-Object Net.Mail.Attachment($Archivo)
    $password = Get-Content "$dir\pw-ccif1.txt" | Convertto-SecureString
    ##
    ##
    $Mensaje = New-Object System.Net.Mail.MailMessage
    $Mensaje.From = $EmailPropio
    $Mensaje.To.Add($EmailDestino)
    $Mensaje.IsBodyHtml = $True
    $Mensaje.Subject = $Asunto
    $Mensaje.Body = $Texto
    $Mensaje.Attachments.Add($Adjunto)
    $ClienteSMTP = New-Object Net.Mail.SmtpClient($ServidorSMTP, 587)
    $ClienteSMTP.EnableSsl = $true
    $ClienteSMTP.Credentials = New-Object System.Net.NetworkCredential($EmailPropio, $password);
    $ClienteSMTP.Send($Mensaje)
    Guardarlo como C:\util\ps\correops.ps1

    Y para ejecutarlo, podeis hacerlo con:

    powershell -executionpolicy remotesigned -File C:\util\ps\correops.ps1

    Si quereis que se ejecuta de forma automatica, ponerlo en el inicio de windows.

    Evidentmente debeis cambiar en él;
    $EmailPropio = "tucuentadegmail@gmail.com";
    $EmailDestino = "cuentadestinocorreo@loquesea.com";


    (puede ser el mismo).

    NOTA: si cuando envieis, falla el script en la ultima linea(en el envio de mensaje) es porque no teneis configurada vuestra cuenta para permitir envios de clientes que gmail llama "no seguros"... es decir, desconocidos para él. Recibireis admeas una alerta de gamil diciendo que alguien lo quiere usar. Para solventar este problema reconfigurarlo en vuestra cuenta de gmail: https://support.google.com/accounts/.../6010255?hl=es
  • noSign
    Super Moderator
    • Dec
    • 4380

    #2
    Originalmente publicado por jmtella Ver Mensaje
    Hace unos días me surgió la necesidad de enviar correos de una forma rápida desde una maquina de la red local cuando se enciende. Enviarlos de una manera sencilla, sin tener instalado nada de correo y que me comunicase su hora de conexión, nombre de maquina y la IP que tiene la maquina en ese momento. La solución es sencilla, un script de powershell lo permite.

    Os dejo un ejemplo de esto, enviado usando una cuenta de gmail, que es lo que aconsejo, ya que gmail permite estos reenvíos directamente. EL problema es que gmail usa seguridad, por lo cual voy a dejar abajo el script completo, incluso enviando un adjunto que lo realiza.

    Igualmente necesitamos poner la password de gmail, y esto no me gusta dejarlo en un script, por lo cual se debe dejar en un fichero encriptado. Para ello, y suponiendo que vamos a dejar los scripts en la carpeta c:\util\ps (cambiarlo si es necesario), lo primero que ejecutamos en un powrshell es:

    Código:
    "tu password gmail" | Convertto-SecureString -AsPlainText -Force | ConvertFrom-SecureString | Out-file "c:\util\ps\pw-ccif.txt"
    Poner en 'tu password gmail' la password de vuestra cuenta de gmail. Esto dejará encriptada la password en el fichero c:\util\ps\pw-ccif.txt (podeis entrar a mirarlo, y ver lo que ha dejado). La encriptacion es "por maquina", es decir hay que ejecutarlo en las maquinas que queramos usar el script y no copiarlo desde otra maquina. Solo, evidentemente hay que hacerlo una vez.

    El script para envío, es:

    Código:
    <#
    Previamente:
    
    "tu password" | Convertto-SecureString -AsPlainText -Force | ConvertFrom-SecureString | Out-file "c:\util\ps\pw-ccif.txt"
    
    Ejecutar como:
    
    powershell -executionpolicy remotesigned -File C:\util\ps\correops.ps1
    
    #>
    $scriptpath = $MyInvocation.MyCommand.Path
    $dir = Split-Path $scriptpath
    #
    $EmailPropio = "tucuentadegmail@gmail.com";
    $EmailDestino = "cuentadestinocorreo@loquesea.com";
    #
    $Asunto = "Conexion: $env:computername $((Get-Date).ToString())"
    $Texto = "Conectado desde $env:computername a las $((Get-Date).ToString())"
    #
    $ServidorSMTP = "smtp.gmail.com"
    $Archivo = "$dir\ipps.txt"
    Get-NetIPAddress -AddressFamily ipv4 | ft IPAddress, InterfaceAlias | out-file -filepath $Archivo
    $Adjunto = New-Object Net.Mail.Attachment($Archivo)
    $password = Get-Content "$dir\pw-ccif1.txt" | Convertto-SecureString
    ##
    ##
    $Mensaje = New-Object System.Net.Mail.MailMessage
    $Mensaje.From = $EmailPropio
    $Mensaje.To.Add($EmailDestino)
    $Mensaje.IsBodyHtml = $True
    $Mensaje.Subject = $Asunto
    $Mensaje.Body = $Texto
    $Mensaje.Attachments.Add($Adjunto)
    $ClienteSMTP = New-Object Net.Mail.SmtpClient($ServidorSMTP, 587)
    $ClienteSMTP.EnableSsl = $true
    $ClienteSMTP.Credentials = New-Object System.Net.NetworkCredential($EmailPropio, $password);
    $ClienteSMTP.Send($Mensaje)
    Guardarlo como C:\util\ps\correops.ps1

    Y para ejecutarlo, podeis hacerlo con:

    powershell -executionpolicy remotesigned -File C:\util\ps\correops.ps1

    Si quereis que se ejecuta de forma automatica, ponerlo en el inicio de windows.

    Evidentmente debeis cambiar en él;
    $EmailPropio = "tucuentadegmail@gmail.com";
    $EmailDestino = "cuentadestinocorreo@loquesea.com";


    (puede ser el mismo).

    NOTA: si cuando envieis, falla el script en la ultima linea(en el envio de mensaje) es porque no teneis configurada vuestra cuenta para permitir envios de clientes que gmail llama "no seguros"... es decir, desconocidos para él. Recibireis admeas una alerta de gamil diciendo que alguien lo quiere usar. Para solventar este problema reconfigurarlo en vuestra cuenta de gmail: https://support.google.com/accounts/.../6010255?hl=es
    Funciona, pero falta un "1" en pw-ccif.txt según el segundo script.:
    "tu password gmail" | Convertto-SecureString -AsPlainText -Force | ConvertFrom-SecureString | Out-file "c:\util\ps\pw-ccif1.txt"

    El script es para SMTP con SSL (puerto 587)
    Yo envio por SMTP con TLS (puerto 465) desde outlook

    Pero si cambio en el script
    $ClienteSMTP = New-Object Net.Mail.SmtpClient($ServidorSMTP, 465)
    $ClienteSMTP.EnableTls = $true



    Me incluye toda las interfaces de red, no solo la que envia.:

    ipps.txt.:
    192.168.220.1 VMware Network Adapter VMnet8
    169.254.41.240 Conexión de área local* 2
    192.168.127.1 VMware Network Adapter VMnet1
    169.254.72.209 Conexión de área local* 1
    169.254.186.117 Ethernet
    192.168.1.35 Wi-Fi
    127.0.0.1 Loopback Pseudo-Interface 1

    Comentario

    • jmtella
      Administrator
      • Nov
      • 20580

      #3
      Originalmente publicado por noSign Ver Mensaje

      Funciona, pero falta un "1" en pw-ccif.txt según el segundo script.:
      "tu password gmail" | Convertto-SecureString -AsPlainText -Force | ConvertFrom-SecureString | Out-file "c:\util\ps\pw-ccif1.txt"

      El script es para SMTP con SSL (puerto 587)
      Yo envio por SMTP con TLS (puerto 465) desde outlook

      Pero si cambio en el script
      $ClienteSMTP = New-Object Net.Mail.SmtpClient($ServidorSMTP, 465)
      $ClienteSMTP.EnableTls = $true



      Me incluye toda las interfaces de red, no solo la que envia.:

      ipps.txt.:
      192.168.220.1 VMware Network Adapter VMnet8
      169.254.41.240 Conexión de área local* 2
      192.168.127.1 VMware Network Adapter VMnet1
      169.254.72.209 Conexión de área local* 1
      169.254.186.117 Ethernet
      192.168.1.35 Wi-Fi
      127.0.0.1 Loopback Pseudo-Interface 1
      Siejpre envia todas las interfaces "INTERNAS" que tiene tu maquina... además es facil a la vista de eso que esatas unido por 192.168.1.35 Wi-Fi. Las 169.254.* es que son autoasignadas, es decir que no hay conectividad o no hay un DCHP que le de direccion, y las VMNet1 y VMNet8 son las de VMWare..

      ¿a que te ha gustado?... y se le puede sacar toda la utilidad que le de tu imaginacion...

      NOTA: he corregido lo del "1" .... échalo una mirada...

      Comentario

      • noSign
        Super Moderator
        • Dec
        • 4380

        #4
        Perfecto, pero lo veo peligroso. ¿No queda constancia de los envios al no pasar por un smtp corporativo?

        Comentario

        • jmtella
          Administrator
          • Nov
          • 20580

          #5
          Originalmente publicado por noSign Ver Mensaje
          Perfecto, pero lo veo peligroso. ¿No queda constancia de los envios al no pasar por un smtp corporativo?
          No queda constancia... como la maquina sea capaz de salir al puerto destino...de esta forma sale...sin que nadie pueda controlarlo ni quede constancia...

          Y esto es un agujero de seguridad que seguramente existe en todas las empresas... y cualquier empleado malicioso podría sacar información confidencial por este camino... sin que quede reflejo de nada.

          Comentario

          • Ferdinand
            Junior Member
            • Apr
            • 1

            #6
            Hola, necesito un poco de orientación a ver si es posible, explico el caso.
            Uso el visor de eventos para el mantenimiento preventivo de algunos equipos y es de altísima ayuda recibir alertas tempranas sobre algunos eventos, el caso que se trata en este post es de lo mejor que he encontrado en la web, estaba probando un script en python con la libreria smtplib (no soy programador ni de cerca ni de lejos) y la seguridad queda algo expuesta, no termina de convencerme, solo me interesa recibir un mail (gmail) donde la unica info que me interesa es lo que diga el subjetc, ya lo tengo andando pero es del tipo rascarse la oreja izquierda con el pié derecho, recibo un mail en el celu que en un golpe de vista se lee en el subject: empresa_(3char)puesto(3char)_severidad(1char), ejem: COL_Agu_1, eso traducido sería: el colegio en puesto de Agustina tiene un error severo
            El script de mas arriba lo puedo usar y formatear externamente de acuerdo a mis intereses pero siento que estoy haciendo lo de rascarme muy "retorcidamente"
            Los eventos que necesito controlar y que son relevantes se pueden dividir en 3 grupos, severos, condicionales e informativos (clasificación mía).
            En los severos están agrupados los eventos que refieren a la integridad/salud de la info: EventID 131 (estructura de archivos), 137 (transaccion de volumen), 98 (ejecute CHKDSK), etc, etc...
            En los condicionales están aquellos que si bien no tratan sobre un desastre inmediato su alta repetición VA A generar algun problema. EventID 41 (mal apagado)
            En los informativos no corre peligro la vida pero tampoco son vitaminas: EventID 129 (restablecimiento de dispositivo, origen: storahci), 27 (network link disconnect)
            La magia que permite hacer esto es: asignar tarea a evento, en la tarea programada llamo a un ejecutable y le puedo pasar parametros
            MI pregunta es: existe la forma de hacer este script con parametros?
            Dada mi edad + problemas de visión hacen que las horas/culo que le dedico a estas cosas cada vez sean menos.
            Mi memoria es malisima, pero creo que a José lo llevo leyendo hace mas de 15 años, salute José!!!!

            Comentario

            • jmtella
              Administrator
              • Nov
              • 20580

              #7
              Originalmente publicado por Ferdinand Ver Mensaje
              Hola, necesito un poco de orientación a ver si es posible, explico el caso.
              Uso el visor de eventos para el mantenimiento preventivo de algunos equipos y es de altísima ayuda recibir alertas tempranas sobre algunos eventos, el caso que se trata en este post es de lo mejor que he encontrado en la web, estaba probando un script en python con la libreria smtplib (no soy programador ni de cerca ni de lejos) y la seguridad queda algo expuesta, no termina de convencerme, solo me interesa recibir un mail (gmail) donde la unica info que me interesa es lo que diga el subjetc, ya lo tengo andando pero es del tipo rascarse la oreja izquierda con el pié derecho, recibo un mail en el celu que en un golpe de vista se lee en el subject: empresa_(3char)puesto(3char)_severidad(1char), ejem: COL_Agu_1, eso traducido sería: el colegio en puesto de Agustina tiene un error severo
              El script de mas arriba lo puedo usar y formatear externamente de acuerdo a mis intereses pero siento que estoy haciendo lo de rascarme muy "retorcidamente"
              Los eventos que necesito controlar y que son relevantes se pueden dividir en 3 grupos, severos, condicionales e informativos (clasificación mía).
              En los severos están agrupados los eventos que refieren a la integridad/salud de la info: EventID 131 (estructura de archivos), 137 (transaccion de volumen), 98 (ejecute CHKDSK), etc, etc...
              En los condicionales están aquellos que si bien no tratan sobre un desastre inmediato su alta repetición VA A generar algun problema. EventID 41 (mal apagado)
              En los informativos no corre peligro la vida pero tampoco son vitaminas: EventID 129 (restablecimiento de dispositivo, origen: storahci), 27 (network link disconnect)
              La magia que permite hacer esto es: asignar tarea a evento, en la tarea programada llamo a un ejecutable y le puedo pasar parametros
              MI pregunta es: existe la forma de hacer este script con parametros?
              Dada mi edad + problemas de visión hacen que las horas/culo que le dedico a estas cosas cada vez sean menos.
              Mi memoria es malisima, pero creo que a José lo llevo leyendo hace mas de 15 años, salute José!!!!
              SI. Powershelll admite parametros sin problemas... mira cualquier manual en la red: busca powershell parametros y tendras decenas de ejemplos.

              Comentario

              Trabajando...
              X