Enviando eventos de Windows Server 2008 R2 por correo.

Aquello que administran servidores, conocen la importancia de los archivos de registro o bitácora (log’s), si son importantes en nuestros equipos de escritorio, a nivel de servidor son de uso vital!!!!

Sea cual sea el sistema operativo del servidor, los registros de eventos: errores críticos y fatales, advertencias e información nos pueden dar la pista de que anda mal en nuestros equipos o que todo funciona de manera correcta.

Básicamente el registro de eventos en los servidores son los «chismosos de la colonia».

Actualmente estoy administrando servidores Wintel, son 4 servidores:

  • Windows Server 2008 con Active Directory y Hyper-V
  • SQL Server 2008 R2
  • SharePoint Server 2008
  • Team Foundation Server 2010

Y como todo no queda bien a la primera, así que todos los días lo primero que tenía que hacer es revisar el Visor de Eventos de cada uno de estos servidores, tarea bastante tediosa, así que decidí investigar un poco la forma en que podía enviarlo a mi correo electrónico.

Dentro de la red había algunas respuestas en la que incluía el Exchange, pero este servidor no lo tengo instalado, así que después de mucho buscar encontré una excelente solución:

Crear una tarea dentro de cada servidor cuando se genera un evento, monitoreo principalmente dos tipos de registros:

  • Aplicaciones
  • Sistema

Así que manos a la obra:
Inicio -> Todos los programas -> Herramientas Administrativas -> Programador de Tareas
Abrir el Programador de Tareas

Posteriormente en el menú seleccionamos la opción de Acción -> Crear tarea…

Creamos la tarea
En la pestaña de General, ponemos los siguientes valores:

  • Nombre y Descripción a nuestra tarea.
  • Opciones de seguridad: Asignamos un usuario con permisos para ejecutar la tarea asignada.
    Es importante señalar que debemos de activar la opción de: Ejecutar tanto si el usuario inicio sesión como si no.

Los datos generales de la tarea.

Pasamos a la pestaña de Desencadenadores

Menú de creación de tarea

Seleccionamos la opción de Al producirse un evento de las opciones de Iniciar la tarea

Cuando se va a ejecutar la tarea.En Configuración marcamos la opción de Personalizada y pulsamos Nuevo filtro del evento.

Vamos a personalizar el eventoVamos a marcar las opciones en Nivel de Evento:

  • Crítico
  • Error
  • Advertencia

También la opción  Por Registro y aquí marcamos Registro de eventos, las opción de Registro de Windows -> Applicaciones

Vamos a seleccionar que filtros vamos a aplicar a los eventos.Nota:

Se van a crear una tarea por cada registro de windows, en mi caso genere dos tareas una para Aplicación y otra para Sistema

Pasamos a la pestaña de Acciones

Menú de creación de tareaEn Acción seleccionamos Iniciar un programa.

Indicamos la acción que se va a realizar.En mi caso particular tengo un directorio en C:\Scripts donde tengo el archivo MonitoreoEventos.ps1 para ejecutar este script se requiere de un parámetro de entrada, comentaremos los parámetros más adelante.

En las pestañas de Condiciones y Configuración, dejamos los valores por defecto.

Pulsamos en Aceptar para guardar nuestra tarea.

De esta manera queda guardada nuestra tarea y se ejecutara cada que se genere un evento.

Bien ahora comentare el script.

El script se genero para Windows PowerShell ¿Que es PowerShell?, que por cierto es una herramienta nueva de MS para los administradores.

Aquí esta el script:

Clear-Host

 

#Datos para el envío de correo.

$EmailFrom=«Registro de eventos<correo@dominio.com>»

$EmailTo=«Cuenta del Administrador<correoAdministrador@dominio.com>»

$SMTPServer=«[SERVIDOR_SMTP]»

$SMTPAuthUsername=«[USUARIO]»

$SMTPAuthPassword=«[CONTRASEÑA]»

#Terminan los datos del envío de correo.

 

# Se verifica si la invocación del script tiene parámetros.

# En caso de que no asigna el registro de System

if($args.Count -eq 0)

{

    $NombreLog=«System»

}

else

{

    $NombreLog=$args[0]

}   

 

#Funcion para envío de correo.

functionenvio_correo {

$mailmessage=New-Objectsystem.net.mail.mailmessage 

$mailmessage.from = ($emailfrom) 

$mailmessage.To.add($emailto)

$mailmessage.Subject =$emailSubject

$mailmessage.Body =$emailbody

$mailmessage.IsBodyHTML =$true

$SMTPClient=New-ObjectNet.Mail.SmtpClient($SmtpServer, 25)  

$SMTPClient.Credentials =New-ObjectSystem.Net.NetworkCredential(«$SMTPAuthUsername», «$SMTPAuthPassword») 

$SMTPClient.Send($mailmessage)

}

#Termina la función de correo.

 

#Funcion de armado de cuerpo de correo.

functionarmado_correo{

 

      # Se arma el asunto del correo.

      # $EmailSubject = «Notificación del servidor: « 

      $EmailSubject=«Notificación del servidor: « 

      $EmailSubject+=$log.MachineName

 

      #Se arma el cuerpo del correo.

      $EmailBody=«El monitor de registros encontro eventos a revisar.»

      $EmailBody+=» <br><br><bold>Por favor de verificar el siguiente evento que se encontro en: <i>$($log.MachineName)</i></bold><br><br>»

      $EmailBody+=«Evento: <b>$($log.EventId)</b> <br><br> «

      $EmailBody+=«Origen: <b>$($log.Source)</b> <br><br> «

      $EmailBody+=«Tipo de evento: <b>$($log.EntryType)</b> <br><br> «

      $EmailBody+=«Se genero: <b>$($log.TimeGenerated)</b> <br><br> «

      $EmailBody+=«Mensaje: <b>$($log.Message)</b> <br><br> «

      $EmailBody+=«Correo generado: <u>$(get-date)</u><br><br>»

 

      &envio_correo

}

 

 

# Obtenemos el registro del evento.

 $log=get-eventlog-logName$NombreLog-newest 1

 

#Verificamos el tipo de evento generado, en caso de ser Informativo, lo dejamos pasar, solo verificamos

# los de error, criticos y advertencias, si se cumple la condición enviamos el correo.

$TipEve=$log.EntryType

 switch ($TipEve){

      Error { &armado_correo; break}

    Warning { &armado_correo; break}

    Critical { &armado_correo; break}

 }

Script para envío de correo de eventos generados.

***** Actualización 10 de Octubre del 2014

Gracias por todos los comentarios y una disculpa por no contestar antes y con respecto a la seguridad en correo pueden probar con esta configuración:

$param = @{
    SmtpServer = 'smtp.gmail.com'
    Port = 587
    UseSsl = $true
    Credential  = 'you@gmail.com'
    From = 'you@gmail.com'
    To = 'someone@somewhere.com'
    Subject = 'Sending emails through Gmail with Send-MailMessage'
    Body = "Check out the PowerShellMagazine.com website!"
    Attachments = 'D:\articles.csv'
}
Send-MailMessage @param
Espero les sirva!!!!

37 comentarios en “Enviando eventos de Windows Server 2008 R2 por correo.

  1. Me da gusto que te haya sido de utilidad!!!! Y gracias por visitar este tu humilde blog, en breve estaré subiendo mas artículos técnicos, tengo en borrador algo de Windows Server 2008 R2 Core, algo para DBA’s, en fin algunos artículos que por falta de tiempo no he podido darles luz verde!!

    • Oscar dijo:

      Hola Cordova, ví tú herramienta y me parece bastante útil. A mí no me quiere correr. ¿qué versión de power shell utilizaste?

  2. pablo dijo:

    me marca error en este dato

    # Obtenemos el registro del evento.
    $log=get-eventlog-logName$NombreLog-newest 1

    El término ‘get-eventlog-logName$NombreLog-newest’ no se reconoce como nombre de un cmdlet, función, archivo de script o programa ejecutable. Compruebe si escribió correctamente el nombre o, si incluyó una ruta de acceso, compruebe que dicha ruta es correcta
    e inténtelo de nuevo.
    En línea: 58 Carácter: 43
    + $log=get-eventlog-logName$NombreLog-newest <<<< 1
    + CategoryInfo : ObjectNotFound: (get-eventlog-logName$NombreLog-newest:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

    • Un favor podrías probar este comando:
      $log =[ ]get-eventlog[ ]-logName[ ]$NombreLog[ ]-newest 1
      Cambia los [ ] por espacios, al parecer en el comando que estas metiendo (get-eventlog-logName$NombreLog-newest) es sin espacios y por eso te provoca el error.
      Inténtalo y me avisas.

      • pablo dijo:

        si eran los espacios gracias, de mucha ayuda amigo. lo coloque de esta forma:

        $log=get-eventlog -logName $NombreLog -newest 1

        pero tengo una pregunta, lo corro y no me envia nada, debe enviarme email siempre o solo cuando se ejecute la tarea o cuando exista un nuevo aviso?

        Gracias nuevamente.

      • aNkeoRuM® dijo:

        Pablo debe enviarte un correo únicamente cada vez que se genere un evento con la categoría elegida en el punto 2 del tutorial (error, crítico o advertencia si seguiste la misma configuración del tutorial). Si no no te va a avisar de nada.

  3. Te envía el correo solo cuando surge un nuevo evento. Dependiendo del nivel de eventos que solicitaste, en el ejemplo activamos los siguientes: Critico, Advertencia y Error, entonces solo cuando se generen estos eventos se va a enviar un correo.

  4. percebe dijo:

    Hola es muy interesante pero no consigo que funcione, que parametro de entrada metes? creo que no lo pusiste, relleno los campos de armado del correo pero no me llega nada al mail, que hago mal? saludos

    • Parámetros de que?? del Correo????
      Estos son los parámetros que mencionas??
      #Datos para el envío de correo.
      $EmailFrom=»Registro de eventos» (Una cuenta que podría ser dedicada para este fin)
      $EmailTo=»Cuenta del Administrador» (Posiblemente tu cuenta o de la persona que requieran que reciba el correo.)
      $SMTPServer=»[SERVIDOR_SMTP]»
      $SMTPAuthUsername=»[USUARIO]»
      $SMTPAuthPassword=»[CONTRASEÑA]»
      Aquí deberás poner los datos de tu servicio de correo.

      Ahora hay que recordar que en base al ejemplo solo te va a mandar correo de los eventos del tipo * Critico, * Error y * Advertencia.
      Este ejemplo lo deje configurando y trabajando en un ambiente de producción y aún sigue funcionando.

      Espero haber resuelto tu duda.

      • Sergio Rodríguez dijo:

        Si, se refiere a en la propia tarea programada, en el apartado de agregar argumentos a la acción, en el pantallazo que pones hay un argumento APPLICATION, esto sirve para algo?

  5. percebe dijo:

    Hola brcordova, gracias por contestar, me refería si pones algun comando especial en argumentos para ejecutar el script, no tengo ni idea de powershell… Esto lo tengo yo parecido con la herramienta blat.exe, pero claro, solo envía un correo de aviso cuando se produce un error y no el error en sí, para eso tendrias que hacerte tareas especificas en cada ID del visor de eventos, por eso es más interesante. Lo que hice fue dar permiso a politica de ejecucion de scripts locales en powershell, copiar tu script tal cual en powershell ISE y rellenar los campos del correo,, guardar a ps1 tal como muestras y armar la tarea, pero no funciona, es un 2008 R2 x64, quiza tengo algo mal de sintasis, hay que dar algun permiso en cortafuegos? saludos.

  6. Enrique dijo:

    Estimado brcordova se me ocurrió que seria de mucha utilidad ejecutar esta tarea de envió de notificación cuando se bloquea o se vence una cuenta de usuario en el dominio, esto seria muy aplicable cuando un servicio utiliza la validación de ldap de windows 2008. Con lo cual los usuarios no ingresan al domino y no son notificados del los bloqueos y vencimientos. Hay algo que se pueda hacer desde el power shell ????

  7. Enrique dijo:

    Hola.

    Quería saber de donde sale la variable $arg que usas para determinar el tipo de evento. Creo que falta una linea.
    He tenido que deshabilitar esa condicional y crear un script para cada registro, poniendo «manualmente» el $NombreLog.

    Gracias.

  8. Miguel dijo:

    Saludos estimado brcordova, queria consultarle como puedo realizar una prueba de que realmente envia correos, porque he seguido los pasos que ud menciona y he realizado eventos en el servidor pero no me envia ninguna informacion al correo…espero sus comentarios.muchas gracias

    • Podrías seleccionar que tambien te envíe en el Nivel de Evento agerga el de Información, para que te mande todo tipo de mensaje y verifiques que esta enviando correctamente los correos, por otro lado verifica si tu servidor requiere de autenticación o algún puerto en especial para que envíe correos.

      • Miguel dijo:

        Muchas gracias por su pronta respuesta, comentarle que efectivamente mi servidor si requiere autentifican y utiliza el puerto 587, como lo puedo configurar en este caso para que envie correctamente?

  9. Acastillo dijo:

    Hola brcordova buen día, una pregunta ya realice la configuración que mencionas al principio, pero en los parámetros del correo en el servidor SMTP como realizo la configuración para el puerto 587, habrá que abrir algún puerto en el firewall de windows? Gracias, muy buen post.

  10. ami dijo:

    hola brcordova hemos realizado tu script y corre bien pero poniendo nuestro datos no nos llega ningún correo y ya realizamos todos los pasos no sabemos si el problema es por el puerto 25 o 587 suponemos como miguel que debemos utilizar el puerto 587 pero no sabemos como habilitarlo para que nos envié el mensaje?

  11. mercedes becerra dijo:

    Hola , ya hemos realizado los cambios por los datos de aca pero solo nos genera un mensaje de error , el siguiente unexpected token get-eventlog[]-logName[]$NombreLog[]-newest
    ya hemos probado sin [] y con [] no mismo si quitamos los [] nos da otros errores como que no reconoce las funciones. Si por favor nos ayudas . Gracias

  12. Rafael dijo:

    Hola buen dia, tengo una duda, sabras si este manual que tu estas dejando aqui en el blog, sirve para monitorear si se me cae un servicio, tengo todo bien configurado, pero lo que mas me urge es saber si se me cae un servicio determinado, espero puedas ayudarme,

    saludos cordiales.

  13. israel dijo:

    perdón el escrip q dejaste sirve para un Windows server 2008 R2 estándar y no c mucho de esto pero el escrip lo guardo como .ps1 y el segundo modulo q pones abajo como lo guardo o es completo en un solo archivo

  14. Isidro dijo:

    ok, me agrado mucho tu blog hay alguna forma de poder monitorear (HealthCheck) de el equipo entero, asi como servicios de SharePoint y que me arroje de la misma forma un correo electrónico

  15. Andrés dijo:

    Muy util tu entrada, sin embargo deseo preguntar si tiene un script que sea un .bat que haga lo mismo que hace el script con .ps1, lo requiero para realizar un trabajo de envío de email cuando algún usuario se loguee al equipo con usuarios Administrador o privilegios de administrador. Por tu valiosa ayuda muchas gracias

  16. Renni dijo:

    amigo cuando programo una tarea y coloco las variables en el cuerpod el correo, me llega es estov

    «Se bloqueo el usuario $(TargetUserName) desde el equipo $(TargetDomainName) al exceder el numero de intentos de ingresos por clave errada. $(SubjectUserName)»

    No me muestra los nombres que veo en los log de seguridad… no se si puedas darme alguna luz referente a esto

  17. Hola!!! Disculpa estoy efectuando todo el proceso tal como esta en el blog y los comentarios pero me ejecuta pero nunca llega el correo. Podrias ayudarme revisando si esta correcto.

    Clear-Host

    #Datos para el envío de correo.
    $EmailFrom=“Registro de eventos”
    $EmailTo=“Cuenta del Administrador”
    $SMTPServer=“[mail.micorreo@micorreo.com]”
    $SMTPAuthUsername=“[micorreo@micorreo.com]”
    $SMTPAuthPassword=“[1234]”
    #Terminan los datos del envío de correo.

    # Se verifica si la invocación del script tiene parámetros.
    # En caso de que no asigna el registro de System
    if($args.Count -eq 0)
    {
    $NombreLog=“System”
    }
    else
    {
    $NombreLog=$args[0]
    }

    #Funcion para envío de correo.
    function envio_correo {
    $mailmessage=New-Objectsystem.net.mail.mailmessage
    $mailmessage.from = ($emailfrom)
    $mailmessage.To.add($emailto)
    $mailmessage.Subject =$emailSubject
    $mailmessage.Body =$emailbody
    $mailmessage.IsBodyHTML =$true
    $SMTPClient=New-ObjectNet.Mail.SmtpClient($SmtpServer, 25)
    $SMTPClient.Credentials =New-ObjectSystem.Net.NetworkCredential(“$SMTPAuthUsername”, “$SMTPAuthPassword”)
    $SMTPClient.Send($mailmessage)
    }
    #Termina la función de correo.

    #Funcion de armado de cuerpo de correo.
    function armado_correo{

    # Se arma el asunto del correo.
    # $EmailSubject = “Notificación del servidor: “
    $EmailSubject=“Notificación del servidor: “
    $EmailSubject+=$log.MachineName

    #Se arma el cuerpo del correo.
    $EmailBody=“El monitor de registros encontro eventos a revisar.”
    $EmailBody+=” Por favor de verificar el siguiente evento que se encontro en: $($log.MachineName)
    $EmailBody+=“Evento: $($log.EventId)
    $EmailBody+=“Origen: $($log.Source)
    $EmailBody+=“Tipo de evento: $($log.EntryType)
    $EmailBody+=“Se genero: $($log.TimeGenerated)
    $EmailBody+=“Mensaje: $($log.Message)
    $EmailBody+=“Correo generado: $(get-date)”

    &envio_correo
    }

    # Obtenemos el registro del evento.
    # $log=get-eventlog-logName$NombreLog-newest 1
    $log=Get-EventLog -LogName $NombreLog -Newest 1
    #Verificamos el tipo de evento generado, en caso de ser Informativo, lo dejamos pasar, solo verificamos
    # los de error, criticos y advertencias, si se cumple la condición enviamos el correo.
    $TipEve=$log.EntryType
    switch ($TipEve){
    Error { &armado_correo; break}
    Warning { &armado_correo; break}
    Critical { &armado_correo; break}
    }

  18. Emilio dijo:

    Magnifica explicación!! una pregunta solo, en «$EmailTo» ¿cómo hacemos para que envío un correo a 2 o más destinatarios? Muchas gracias!

Deja un comentario