Page 1 of 2

Info Output Custom Plugin

Posted: Wed Apr 02, 2014 9:06 am
by WillemDH
Hello,

I noticed that it seems not possible to get the full information of a service problem that happened in the past.

For example:

Code: Select all

***** Nagios XI Alert *****

Nagios has detected a problem with this service.

Notification Type: PROBLEM

Service: SRV_MS_Win_Tasks
Host: servername
Address: 10.22.22.22
State: CRITICAL
Info:
1 / 59 tasks failed! Check tasks:
Date/Time: 29/03/2014 00:48:01
So the Powershell plugin will first return information summary with a write-host and than use write-host again for each failed task. But I need to be able to see which tasks failed in the past. When I go to service history, I only see the first line, just like in the email. I also would like the write-host outputs beyond the first to be visible in the service history and emails.

Any idea how I should do this? Can I only use write-host once? Or is it because I'm using multiple lines? Or can I somehow look up this extended information with the failed tasks somewhere else in Nagios?

Grtz

Willem

Re: Info Output Custom Plugin

Posted: Wed Apr 02, 2014 12:42 pm
by abrist
Have you ever seen the multiline output in the nagios xi ui, or just the first line? If you only ever see the first line, you may have an issue with your script.

Re: Info Output Custom Plugin

Posted: Thu Apr 03, 2014 2:29 am
by WillemDH
Andy,

I can see the multiline output when the service is in critical state and I go to the service overview tab. I can't see the lines beyond the first when I go to service history.

Grtz

Re: Info Output Custom Plugin

Posted: Thu Apr 03, 2014 1:08 pm
by sreinhardt
You really only want to write a single line, by that I mean no actual newline characters. However if you pass back \n from the plugin where you would like a newline character, nagios will respect that in notifications and in the interface. This should allow you to get all the information in most if not all places. Otherwise it will often get cut off like you saw, at the first newline char.

Usually I create an outputmsg object and += anything I need onto it, then use one write-host at the end to output that entire string.

Re: Info Output Custom Plugin

Posted: Thu Apr 03, 2014 1:46 pm
by WillemDH
Thanks Spencer, I get what you mean and will try this asap.

Re: Info Output Custom Plugin

Posted: Thu Apr 03, 2014 1:47 pm
by sreinhardt
No problem! Let me know how it goes.

Re: Info Output Custom Plugin

Posted: Thu Apr 17, 2014 8:29 am
by WillemDH
Hey Spencer,

In the meantime I updated the script (https://github.com/willemdh/check_ms_win_tasks.ps1) and I'm only doing one write-host with a combined output of strings. But I still have the same problem. In the service history I can only see the first line.

Code: Select all

if ($TaskNotOk -gt "0") {
	$OutputString += "$TaskNotOk / $TotalTasks tasks failed! Check tasks: `r`n"
	foreach ($BadTask in $BadTasks) {
		$OutputString += "Task $($BadTask.Name) by $($BadTask.Author) failed with exitcode $($BadTask.lasttaskresult)`r`n"
	}
	foreach ($RunningTask in $RunningTasks) {
		$OutputString += "Task $($RunningTask.Name) by $($RunningTask.Author), exitcode $($RunningTask.lasttaskresult) is still running!`r`n"
	}
	$OutputString +=  " | 'Total Tasks'=$TotalTasks, 'OK Tasks'=$TaskOk, 'Failed Tasks'=$TaskNotOk, 'Running Tasks'=$TaskRunning"
	$status = 2
}	
else {
	$OutputString +=  "All $TotalTasks tasks ran succesfully!`r`n"
	foreach ($RunningTask in $RunningTasks) {
		$OutputString +=  "Task $($RunningTask.Name) by $($RunningTask.Author), exitcode $($RunningTask.lasttaskresult) is still running!`r`n"
	}
	$OutputString +=  " | 'Total Tasks'=$TotalTasks, 'OK Tasks'=$TaskOk, 'Failed Tasks'=$TaskNotOk, 'Running Tasks'=$TaskRunning"
	$status = 0
}
Write-Host "$outputString"
The above is the code, which creates the $OutputString. As you can see in the uploaded image I can only see "$TaskNotOk / $TotalTasks tasks failed! Check tasks: `r`n" and not the subsequent lines which lists the failed tasks and their owner. As I have some servers with 50 and more scheduled tasks, not knowing which tasks failed at what tdate / time is not really the purpose.

Any other tips? I could of course use no newline at all and just paste all the failed tasks in one line, but I'd like to use one line for each failed task..

I even tried inserting a <br> instead of `r`n , but I get

Code: Select all

1 / 59 tasks failed! Check tasks: <br>Task BW_Buurtwerk by demeyerfailed with exitcode 267014<br>
as output.

Grtz

Willem

Re: Info Output Custom Plugin

Posted: Thu Apr 17, 2014 3:38 pm
by sreinhardt
Try replacing all of your literal newline and carriage returns (`r`n) with the linux\C version (\r\n). This should put the entire line on a single line for nrpe to return and when interpreted and put into notifications or the nagios screen, it will show actual newlines but should also show everything in your message.

Also, you might not even need the \r any longer.

Output goes from:

Code: Select all

PS> .\willem.ps1 localhost '' ''
All 0 tasks ran succesfully!
 | 'Total Tasks'=0, 'OK Tasks'=0, 'Failed Tasks'=0, 'Running Tasks'=0
To:

Code: Select all

PS> .\willem.ps1 localhost '' ''
All 0 tasks ran succesfully!\r\n | 'Total Tasks'=0, 'OK Tasks'=0, 'Failed Tasks'=0, 'Running Tasks'=0
The changed code looks like:

Code: Select all

###################################################################################################
# Script name:   	check_ms_win_tasks.ps1
# Version:			2.14.4.11
# Created on:    	01/02/2014																			
# Author:        	D'Haese Willem
# Purpose:       	Checks Microsoft Windows scheduled tasks excluding defined folders and defined 
#					task patterns, returning state of tasks with name, author, exit code and 
#					performance data to Nagios.
# On Github:		https://github.com/willemdh/check_ms_win_tasks.ps1
# To do:			
#  	- Add switches to change returned values and output
#  	- Add array parameter with exit codes that should be excluded
#	- Make parameters non mandatory
#	- Test remote execution
# History:       	
#	03/02/2014 => Add array as argument with excluded folders
#	15/02/2014 => Add array as argument with excluded task patterns
#	03/03/2014 => Added perfdata and edited output
#	09/03/2014 => Added running tasks information and perfdata
#	22/03/2014 => Resolved a bug with output treated as perfdata
#	23/03/2014 => Created repository on Github and updated documentation
#	11/04/2014 => New output format with outputstring to be able to see failed tasks in service history
#	11/04/2014 => Added [int] to prevent decimal numbers
# How to:
#	1) Put the script in the NSCP scripts folder
#	2) In the nsclient.ini configuration file, define the script like this:
#		check_ms_win_tasks=cmd /c echo scripts\check_ms_win_tasks.ps1 $ARG1$ $ARG2$ $ARG3$; exit 
#		$LastExitCode | powershell.exe -command -
#	3) Make a command in Nagios like this:
#		check_ms_win_tasks => $USER1$/check_nrpe -H $HOSTADDRESS$ -p 5666 -t 60 -c 
#		check_ms_win_tasks -a $ARG1$ $ARG2$ $ARG3$
#	4) Configure your service in Nagios:
#		- Make use of the above created command
#		- Parameter 1 should be 'localhost' (did not test with remoting)
#		- Parameter 2 should be an array of folders to exclude, example 'Microsoft, Backup'
#		- Parameter 3 should be an array of task patterns to exclude, example 'Jeff,"Copy Test"'
#		- All single quotes need to be included (In Nagios XI)
#		- Array values with spaces need double quotes (see above example)
#		- All three parameters are mandatory for now, use " " if you don't want exclusions
# Help:
#	This script works perfectly in our environment on Windows 2008 and Windows 2008 R2 servers. If
#	you do happen to find an issue, let me know on Github. The script is highly adaptable if you 
#	want different output etc. I've been asked a few times to make it multilingual, as obviously
#	this script will only work on English Windows 2008 or higher servers, but as I do not have 
#	non-English servers at my disposal, I'm not going to implement any other languages..
# Copyright:
#	This program is free software: you can redistribute it and/or modify it under the terms of the
# 	GNU General Public License as published by the Free Software Foundation, either version 3 of 
#   the License, or (at your option) any later version.
#   This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
#	without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
# 	See the GNU General Public License for more details.You should have received a copy of the GNU
#   General Public License along with this program.  If not, see <http://www.gnu.org/licenses/>.
###################################################################################################


param(
	[Parameter(Mandatory=$true)][string]$ComputerName = "localhost",
    [Parameter(Mandatory=$true)]$ExclFolders = @(),
	[Parameter(Mandatory=$true)]$ExclTasks = @(),
	[switch]$RootFolder
)
 
#region Functions
function Get-AllTaskSubFolders {
    [cmdletbinding()]
    param (
       $FolderRef = $Schedule.getfolder("\")
    )
    if ($RootFolder) {
        $FolderRef
    } else {
        $FolderRef	     
        if(($folders = $folderRef.getfolders(1)).count -ge 1) {
            foreach ($folder in $folders) {
				if ($ExclFolders -notcontains $folder.Name) {     
                	if(($folder.getfolders(1).count -ge 1)) {
                    	Get-AllTaskSubFolders -FolderRef $folder
                	}
					else {
						$folder
					}
				}
            }
        }
    }
}

function Check-Array ([string]$str, [string[]]$patterns) {
    foreach($pattern in $patterns) { if($str -match $pattern) { return $true; } }
    return $false;
}

#endregion Functions

if ($PSVersionTable) {$Host.Runspace.ThreadOptions = 'ReuseThread'}
 
$status = 3;
 
try {
	$schedule = new-object -com("Schedule.Service") 
} catch {
	Write-Host "Schedule.Service COM Object not found, this script requires this object"
	exit $status
	return
}
 

$Schedule.connect($ComputerName) 
$AllFolders = @()
$AllFolders = Get-AllTaskSubFolders
[int]$TaskOk = 0
[int]$TaskNotOk = 0
[int]$TaskRunning = 0
[int]$TotalTasks = 0
$BadTasks = @()
$GoodTasks = @()
$RunningTasks = @()
$OutputString = ""


foreach ($Folder in $AllFolders) {		
		    if (($Tasks = $Folder.GetTasks(0))) {
		        $Tasks | Foreach-Object {$ObjTask = New-Object -TypeName PSCustomObject -Property @{
			            'Name' = $_.name
		                'Path' = $_.path
		                'State' = $_.state
		                'Enabled' = $_.enabled
		                'LastRunTime' = $_.lastruntime
		                'LastTaskResult' = $_.lasttaskresult
		                'NumberOfMissedRuns' = $_.numberofmissedruns
		                'NextRunTime' = $_.nextruntime
		                'Author' =  ([xml]$_.xml).Task.RegistrationInfo.Author
		                'UserId' = ([xml]$_.xml).Task.Principals.Principal.UserID
		                'Description' = ([xml]$_.xml).Task.RegistrationInfo.Description
						'Cmd' = ([xml]$_.xml).Task.Actions.Exec.Command 
						'Params' = ([xml]$_.xml).Task.Actions.Exec.Arguments
		            }
				if ($ObjTask.LastTaskResult -eq "0") {
					if(!(Check-Array $ObjTask.Name $ExclTasks)){
						$GoodTasks += $ObjTask
						$TaskOk += 1
						}
					}
				elseif ($ObjTask.LastTaskResult -eq "0x00041301") {
					if(!(Check-Array $ObjTask.Name $ExclTasks)){
						$RunningTasks += $ObjTask
						$TaskRunning += 1
						}
					}
				else {
					if(!(Check-Array $ObjTask.Name $ExclTasks)){
						$BadTasks += $ObjTask
						$TaskNotOk += 1
						}
					}
				}
		    }	
} 
$TotalTasks = $TaskOk + $TaskNotOk + $TaskRunning
if ($TaskNotOk -gt "0") {
	$OutputString += "$TaskNotOk / $TotalTasks tasks failed! Check tasks: \r\n"
	foreach ($BadTask in $BadTasks) {
		$OutputString += "Task $($BadTask.Name) by $($BadTask.Author) failed with exitcode $($BadTask.lasttaskresult)\r\n"
	}
	foreach ($RunningTask in $RunningTasks) {
		$OutputString += "Task $($RunningTask.Name) by $($RunningTask.Author), exitcode $($RunningTask.lasttaskresult) is still running!\r\n"
	}
	$OutputString +=  " | 'Total Tasks'=$TotalTasks, 'OK Tasks'=$TaskOk, 'Failed Tasks'=$TaskNotOk, 'Running Tasks'=$TaskRunning"
	$status = 2
}	
else {
	$OutputString +=  "All $TotalTasks tasks ran succesfully!\r\n"
	foreach ($RunningTask in $RunningTasks) {
		$OutputString +=  "Task $($RunningTask.Name) by $($RunningTask.Author), exitcode $($RunningTask.lasttaskresult) is still running!\r\n"
	}
	$OutputString +=  " | 'Total Tasks'=$TotalTasks, 'OK Tasks'=$TaskOk, 'Failed Tasks'=$TaskNotOk, 'Running Tasks'=$TaskRunning"
	$status = 0
}
Write-Host "$outputString"
exit $status

Re: Info Output Custom Plugin

Posted: Tue Apr 22, 2014 7:36 am
by WillemDH
Hi Spenser,

Just replaced all `r`n by \r\n but I'm still having the same issue.

The service state history only show "1 / 59 tasks failed! Check tasks: \r" and not which tasks are failed.

Grtz.

Re: Info Output Custom Plugin

Posted: Tue Apr 22, 2014 9:05 am
by tmcdonald
If you want newlines in a web page I think you need to use <br /> HTML tags in place of the newlines. Yes it might look a little weird on the command line, but that's how HTML works.