Envío de alertas con Task Scheduler

I Love PowerShell, como hoy es el día de los enamorados quería tener un pequeño detalle con una herramienta a la que cada vez estoy cogiendo más aprecio, aunque muchos piensan que es solo para los administradores de sistemas, están muy equivocados, también es una herramienta para los desarrolladores. En esta ocasión he podido implementar una funcionalidad de monitorización con PowerShell y el TaskScheduler de Winwdows.

Mediante el programador de tareas de Windows 2008 podemos planificar tareas en base a un evento de sistema e incluso podemos añadirle ciertas condiciones. Para mí una de las funcionalidades más interesantes es la de poder notificar vía mail al producirse un error crítico en nuestro aplicativo. En concreto lo estoy utilizando para notificar errores de mis componentes de SharePoint, mediante el servicio SPDiagnosticsService podemos realizar una entrada en el log de sucesos windows con nuestro propio código con un código similar al siguiente:

SPDiagnosticsService diagSvc = SPDiagnosticsService.Local; 
WriteEvent(MiCodigoDeError, new SPDiagnosticsCategory(CATEGORIA, TraceSeverity.VerboseEx, EventSeverity.Error), Microsoft.SharePoint.Administration.EventSeverity.ErrorCritical, "Exception: {0} {1}”, new object[] { ex.Message, ex.StackTrace});

Una vez dispongamos de una entrada en el log de windows podemos asociarle una tarea seleccionando el evento y pulsando en “Attach task to this Event…”, se iniciará entonces un asistente para definir la tarea asociada al evento pudiendo seleccionar entre tres tipos de acciones: lanzar un programa, enviar un mail y mostrar un mensaje. Aunque lo ideal sería seleccionar la acción de “Enviar un mail” lo cierto es que esta acción solo envía un mail estático por lo que no podremos utilizarla si deseamos que nos indique en el mail el mensaje del evento que lanzó la acción.

Aquí es donde llega nuestro amigo PowerShell, con el que obtendremos el mensaje del último evento producido y enviáremos un mail con el formato que deseemos Sonrisa

imageimage

 

Lo primero será obtener el mensaje del evento que lanzó la tarea programada, para ello dispondremos del cmdlet Get-WinEvent. Con el siguiente script podremos por ejemplo obtener un listado con todas las entradas en el log de windows con el código 4664: 

Get-WinEvent -LogName "Application" | where {$_.Id -eq 4664} 

image

Para obtener el último mensaje limitaremos los resultados a 1 elemento y poder manejar una instancia de la clase :

$event = Get-WinEvent -LogName "Application" -MaxEvents 1 | where {$_.Id -eq 4664} 

$event.Message

image

Ahora solo quedaría componer el mail de la siguiente forma:


$emailFrom = "mailorigen" 
$emailTo = "maildestino" 
$subject = "Error portal" 
$body = $event.MachineName + "    " + $event.Message

$smtpServer = "DirecciónSMTP"
$smtp = new-object Net.Mail.SmtpClient($smtpServer) 
$smtp.Send($emailFrom, $emailTo, $subject, $body)

Una vez tengamos el script completo lo guardaremos en un fichero con extensión “.ps1” e indicaremos en la acción que ejecute nuestro ps1 con una expresión similar a la siguiente:

%SystemRoot%system32WindowsPowerShellv1.0powershell.exe –Noninteractive C:WindowsSystem32TaskSendMail.ps1

image

Publicado por

Mario Cortés

Mario Cortés Flores es MVP en Office 365, trabaja en Plain Concepts como Team Lead y escribe habitualmente en geeks.ms/blogs/mcortes y en Twitter @mariocortesf. Podréis encontrarlo colaborando activamente con la comunidad de MadPoint y SUGES

5 comentarios en “Envío de alertas con Task Scheduler”

  1. Al final sí que conseguirás que nos aficionemos al PowerShell… 😉
    Desde que leo tus posts ni se me ocurre ya decir que sólo es para los IT.
    Gracias

  2. Marius….entiendo que de esa forma, envías el último log. Si llegan dos errores seguidos, envías dos veces el mismo error, ¿no?

    Cuando se lanza la tarea……¿no se envia el identificador del logitem que la ha lanzado?

  3. Efectivamente, si entran varias entradas iguales al mismo tiempo e script podría notificar el error que no debe. Por eso lo importante es asociarlo a los id’s de evento o categorías más críticos, de esta forma si recibimos un mail procedente de un error crítico nos daría igual que fueran dos ya que lo que importaría sería que ha existido un error crítico y estamos informados 😉

    En cualquier caso lo suyo sería utilizar System Center para SharePoint, pero no siempre es posible.

    Gracias por la observación.

  4. Gran post, felicidades, como sería si quisiera que me reportara todo los errores de aplicaciones:

    Get-WinEvent -LogName “Application” | where {$_.level -eq error}

    $event = Get-WinEvent -LogName “Application” -MaxEvents 10 | where {$_.level -eq error}

    $emailFrom = “mailorigen”
    $emailTo = “maildestino”
    $subject = “Error portal”
    $body = $event.MachineName + ” ” + $event.Message

    $smtpServer = “DirecciónSMTP”
    $smtp = new-object Net.Mail.SmtpClient($smtpServer)
    $smtp.Send($emailFrom, $emailTo, $subject, $body)

    $event.Message

    ¿y si quisiera que me reportase todos los errores del día anterior, definirlo por fecha?.
    gracias y saludos.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *