Page 1 of 2

Check works on some systems- but not all.

Posted: Tue Jun 20, 2017 3:18 pm
by JohnFLi
I have a check (powershell) that checks for the last time windows updates were applied.
it works fine on some systems, but not all.
on the systems it is NOT working on, the nsclient.log file says :

Code: Select all

2017-06-20 13:02:26: e:c:\build\nscp\include\socket/connection.hpp:146: Failed to send data: The file handle supplied is not valid
when I run the command from cli on teh nagios server it reports:

Code: Select all

 ./check_nrpe -H g1ppdc02 -t 120 -c check_updates -a 30
CHECK_NRPE: Received 0 bytes from daemon.  Check the remote server logs for error messages.
I have tried it with a timeout of 5 min, with the same result. In XI, I copied the check from one of the systems that it works just fine on - then changed the host it would check it against of course.

the NSclient version I have on all the systems is: 0.4.1.105

when I run the powershell script on the windows machine, it works fine and dandy.

the script it:

Code: Select all

param($warn)
#$GracePeriod = 30
#$output1 = $warn | out-file c:\scripts\grace.txt
$GracePeriod = $warn


Function Check-NewUpdates {


$OSVersion = Check-OSVersion



If ( $GracePeriod -ne $null ) { #If GracePeriod is set
	$UpdateTime = Check-LastUpdate $GracePeriod
	
	If ($UpdateTime.IsOver -eq $true) { #If is outside of GP, check for updates and return
		$Updates = Check-Updates
		$Output = Create-Output $Updates
	}
	ElseIF ($UpdateTime.IsOver -eq $false) { #If within GP, return days since check with OK status
        $Output = @{}
        $Output.Output = "Within grace period."
        $Output.ExitCode = 0
	}
} #ends if GP is set
	
Else { # If no grace period has been set, check and return
	$UpdateTime = Check-LastUpdate 0
	$Updates = Check-Updates
	$Output = Create-Output $Updates
}

$days = $UpdateTime.Days
$OutputString = $Output.Output
Write-Output "$days Days since last update. $OutputString"
Exit $Output.ExitCode
}

# Function to check OS Version and return string with 7 or XP depending. Returns [string]
Function Check-OSVersion {
    
    $version = Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion'
    
    switch ($($version.CurrentVersion).split(".")[0]){
        6 { [string]$Return = "7" }
        5 { [string]$Return = "XP" }
    } ## End of Switch to check versioning
    
    Return $Return

} ## End of Function

# Checks for updates using winupdate api, returns hashtable with all listed updates not including hidden ones. Returns [Array](KBImportance)KB and [Int](KBImportance)Number
Function Check-Updates {
	
	$Return = @{}
	[string]$Return.CriticalKB = ""
	[Int]$Return.CriticalNumber = 0
	[string]$Return.ImportantKB = ""
	[Int]$Return.ImportantNumber = 0
	[string]$Return.ModerateKB = ""
	[Int]$Return.ModerateNumber = 0
	[string]$Return.LowKB = ""
	[Int]$Return.LowNumber = 0
    [string]$Return.UnknownKB = ""
	[Int]$Return.UnknownNumber = 0
	
	$Updates = $( New-Object -ComObject Microsoft.Update.Session ).CreateUpdateSearcher().Search("IsAssigned=1 and IsHidden=0 and IsInstalled=0").Updates
	
	$Updates | Where {$_.MsrcSeverity -eq "Critical" } |  ForEach-Object { $_.KbArticleIDs } | Sort -Unique | ForEach-Object { 
			$Return.CriticalNumber++
			$Return.CriticalKB += "KB"+$_+"\n"
			}
			
	$Updates | Where {$_.MsrcSeverity -eq "Important" } |  ForEach-Object { $_.KbArticleIDs } | Sort -Unique | ForEach-Object {
			$Return.ImportantNumber++
			$Return.ImportantKB += "KB"+$_+"\n"
			}
		
	$Updates | Where {$_.MsrcSeverity -eq "Moderate" } |  ForEach-Object { $_.KbArticleIDs } | Sort -Unique | ForEach-Object { 
			$Return.ModerateNumber++
			$Return.ModerateKB += "KB"+$_+"\n"
			}
			
	$Updates | Where {$_.MsrcSeverity -eq "Low" } |  ForEach-Object { $_.KbArticleIDs } | Sort -Unique | ForEach-Object {
			$Return.LowNumber++
			$Return.LowKB += "KB"+$_+"\n"
			}

    $Updates | Where-Object {!$_.MsrcSeverity} |  ForEach-Object { $_.KbArticleIDs } | Sort -Unique | ForEach-Object {
			$Return.UnknownNumber++
			$Return.UnknownKB += "KB"+$_+"\n"
			}
	
	Return $Return
} # Ends Function

# Checks if last update installed was within Grace Period, Returns [Int]Days and [Boolean]IsOver
Function Check-LastUpdate {

	Param([Parameter(Mandatory=$true)][Int]$GracePeriod)
	
	$Return = @{}
	
	#Gets DateTime Object with last update installed
	if ($(Check-OSVersion) -eq "7") {
		$WMIData = Get-WmiObject -Class Win32_QuickFixEngineering 
	}
	Else { $WMIData = $null }
	
    If ( $WMIData -eq $null ) { ## No data for installed on, run update check, might be issue with os version too
        
        $Return.Days = 0
        $Return.IsOver = $true
    }
    
    Else { ## has data and should be processed
        
        [DateTime]$Date = $( $WMIData | Sort InstalledOn -Descending -Unique | Select InstalledOn -First 1 ).InstalledOn
        
        $Return.Days =  $( $(Get-Date) - $Date).Days
    	
    	If ( $Return.Days -gt $GracePeriod ) { #if true has been longer than grace period
    		
    		$Return.IsOver = $true
    	}
    	Else { #if within Grace Period
    	
    		$Return.IsOver = $false
    	}
    }
    
	Return $Return
}

# Creates write-ouput text for returning data to nagios, Returns [int]ExitCode and [string]Output
Function Create-Output {
	Param ( [Parameter(Mandatory=$true)]$Updates )
	
	$Return = @{}
	[Int]$Return.ExitCode = 3 # Sets to unknown by default
	[String]$Return.Output = "Output creation failed, something is not working!"
	
	If ( $Updates.CriticalNumber -gt 0 ) { # If any Critical updates, writes output line and sets exit code to 2(critical)
		$Return.ExitCode = 2
		$Return.Output = "`n"+$Updates.CriticalNumber+" Critical Updates:"
		
		$Return.Output += "`n"+$Updates.CriticalKB.Replace("\n","`n")
		

		If ($Updates.ImportantNumber -gt 0)	{$Return.Output += ""+$Updates.ImportantNumber+" Important Updates:`n"
											 $Return.Output += $Updates.ImportantKB.Replace("\n","`n")
		    								}		
		If ($Updates.ModerateNumber -gt 0) 	{$Return.Output += ""+$Updates.ModerateNumber+" Moderate Updates:`n"
											 $Return.Output += $Updates.ModerateKB.Replace("\n","`n")
											}		
		If ($Updates.LowNumber -gt 0) 		{$Return.Output += ""+$Updates.LowNumber+" Low Updates:`n"
											 $Return.Output += $Updates.LowKB.Replace("\n","`n")
											}
        If ($Updates.UnknownNumber -gt 0)	{$Return.Output += ""+$Updates.UnknownNumber+" Unknown Updates:`n"
											 $Return.Output += $Updates.UnknownKB.Replace("\n","`n")
											}

	} #Ends Critical If
	
	ElseIf ( $Updates.ImportantNumber -gt 0 ) { # If any Important updates, writes output line and sets exit code to 2(critical)
		$Return.ExitCode = 2
		$Return.Output = "`n"+$Updates.ImportantNumber+" Important Updates:"
		
		$Return.Output += "`n"+$Updates.ImportantKB.Replace("\n","`n")
		
		If ($Updates.ModerateNumber -gt 0) 	{$Return.Output += ""+$Updates.ModerateNumber+" Moderate Updates:`n"
											 $Return.Output += $Updates.ModerateKB.Replace("\n","`n")
											}		
		If ($Updates.LowNumber -gt 0) 		{$Return.Output += ""+$Updates.LowNumber+" Low Updates:`n"
											 $Return.Output += $Updates.LowKB.Replace("\n","`n")
											}
        If ($Updates.UnknownNumber -gt 0)	{$Return.Output += ""+$Updates.UnknownNumber+" Unknown Updates:`n"
											 $Return.Output += $Updates.UnknownKB.Replace("\n","`n")
											}
	} #Ends Important If

	ElseIf ( $Updates.ModerateNumber -gt 0 ) { # If any Moderate updates, writes output line and sets exit code to 1(Warning)
			$Return.ExitCode = 1
			$Return.Output = "`n"+$Updates.ModerateNumber+" Moderate Updates:"
			
			$Return.Output += "`n"+$Updates.ModerateKB.Replace("\n","`n")
			
			If ($Updates.LowNumber -gt 0) 		{$Return.Output += ""+$Updates.LowNumber+" Low Updates:`n"
												 $Return.Output += $Updates.LowKB.Replace("\n","`n")
											}
            If ($Updates.UnknownNumber -gt 0) 	{$Return.Output += ""+$Updates.UnknownNumber+" Unknown Updates:`n"
												 $Return.Output += $Updates.UnknownKB.Replace("\n","`n")
											}
		} #Ends Moderate If
	
	ElseIf ( $Updates.LowNumber -gt 0 ) { # If any Low updates, writes output line and sets exit code to 1(Warning)
		    $Return.ExitCode = 1
		    $Return.Output = "`n"+$Updates.LowNumber+" Low Updates:"
		
		    $Return.Output += "`n"+$Updates.LowKB.Replace("\n","`n")
            If ($Updates.UnknownNumber -gt 0) 	{$Return.Output += ""+$Updates.UnknownNumber+" Unknown Updates:`n"
												 $Return.Output += $Updates.UnknownKB.Replace("\n","`n")
											}
            
		
	} #Ends Low If
    
    ElseIf ($Updates.UnknownNumber -gt 0) { # If number of unknown severity updates are available sets exit to 1(warning)
        $Return.ExitCode = 1
		$Return.Output = "`n"+$Updates.UnknownNumber+" Unknown Updates:"
		
		$Return.Output += "`n"+$Updates.UnknownKB.Replace("\n","`n")
    }

	ElseIf ( ($Updates.CriticalNumber -eq 0) -and ($Updates.ImportantNumber -eq 0) -and ($Updates.ModerateNumber -eq 0) -and ($Updates.LowNumber -eq 0) -and ($Updates.UnknownNumber -eq 0) ) { #If no updates, writes output and sets exit 0(OK)
		$Return.ExitCode = 0
		$Return.Output = "There are no updates to be done."
	}
	
	Return $Return
}

Check-NewUpdates $GracePeriod
There has got to be somethign I am missing

Re: Check works on some systems- but not all.

Posted: Tue Jun 20, 2017 3:23 pm
by dwhitfield
Can you post all of the NSClient.ini files that are not working and label them in some way? If it's dozens, just pick one and stick to that one so it doesn't get confusing.

Also, you might try updating NSClient to .4.4. We don't technically support .4.1 (although I understand it's probably the version you are using on the working servers)

Re: Check works on some systems- but not all.

Posted: Tue Jun 20, 2017 3:32 pm
by cdienger
Where did you set the 5 minute timeout? I found http://forums.nsclient.org/t/powershell ... 03/3239/13 which appears to be the same problem you're running into and MickeM pointed out some time out setting in http://docs.nsclient.org/faq/#42-timeout-issues.

Re: Check works on some systems- but not all.

Posted: Tue Jun 20, 2017 3:39 pm
by JohnFLi
the ini file, for both, the good and the bad is:
(I have a bat file that I created that copies the ini file to my servers, that way I know all are the same)

Code: Select all

# If you want to fill this file with all avalible options run the following command:
#   nscp settings --generate --add-defaults --load-all
# If you want to activate a module and bring in all its options use:
#   nscp settings --activate-module <MODULE NAME> --add-defaults
# For details run: nscp settings --help


; Undocumented section
[/modules]

; CheckDisk - CheckDisk can check various file and disk related things. The current version has commands to check Size of hard drives and directories.
CheckDisk = 1

; Event log Checker. - Check for errors and warnings in the event log. This is only supported through NRPE so if you plan to use only NSClient this wont help you at all.
CheckEventLog = 1

; Check External Scripts - A simple wrapper to run external scripts and batch files.
CheckExternalScripts = 1

; Helper function - Various helper function to extend other checks. This is also only supported through NRPE.
CheckHelpers = 1

; Check NSCP - Checkes the state of the agent
CheckNSCP = 1

; CheckSystem - Various system related checks, such as CPU load, process state, service state memory usage and PDH counters.
CheckSystem = 1

; CheckWMI - CheckWMI can check various file and disk related things. The current version has commands to check Size of hard drives and directories.
CheckWMI = 1

; NRPE server - A simple server that listens for incoming NRPE connection and handles them.
NRPEServer = 1

; NSClient server - A simple server that listens for incoming NSClient (check_nt) connection and handles them. Although NRPE is the preferred method NSClient is fully supported and can be used for simplicity or for compatibility.
NSClientServer = 1

NSCAClient = 1
NSClientServer = 1

[/settings/NRPE/server]

; COMMAND ARGUMENT PROCESSING - This option determines whether or not the we will allow clients to specify arguments to commands that are executed.
allow arguments = true

; COMMAND ALLOW NASTY META CHARS - This option determines whether or not the we will allow clients to specify nasty (as in |`&><'"\[]{}) characters in arguments.
allow nasty characters = true

; Undocumented section
[/settings/default]

; ALLOWED HOSTS - A comaseparated list of allowed hosts. You can use netmasks (/ syntax) or * to create ranges.
allowed hosts = g1vpnag03,g1vppcinag


; A list of aliases available. An alias is an internal command that has been "wrapped" (to add arguments). Be careful so you don't create loops (ie check_loop=check_a, check_a=check_loop)
[/settings/external scripts/alias]

; alias_cpu - Alias for alias_cpu. To configure this item add a section called: /settings/external scripts/alias/alias_cpu
alias_cpu = checkCPU warn=80 crit=90 time=5m time=1m time=30s

; alias_cpu_ex - Alias for alias_cpu_ex. To configure this item add a section called: /settings/external scripts/alias/alias_cpu_ex
alias_cpu_ex = checkCPU warn=$ARG1$ crit=$ARG2$ time=5m time=1m time=30s

; alias_disk - Alias for alias_disk. To configure this item add a section called: /settings/external scripts/alias/alias_disk
alias_disk = CheckDriveSize MinWarn=10% MinCrit=5% CheckAll FilterType=FIXED

; alias_disk_loose - Alias for alias_disk_loose. To configure this item add a section called: /settings/external scripts/alias/alias_disk_loose
alias_disk_loose = CheckDriveSize MinWarn=10% MinCrit=5% CheckAll FilterType=FIXED ignore-unreadable

; alias_event_log - Alias for alias_event_log. To configure this item add a section called: /settings/external scripts/alias/alias_event_log
alias_event_log = CheckEventLog file=application file=system MaxWarn=1 MaxCrit=1 "filter=generated gt -2d AND severity NOT IN ('success', 'informational') AND source != 'SideBySide'" truncate=800 unique descriptions "syntax=%severity%: %source%: %message% (%count%)"

; alias_file_age - Alias for alias_file_age. To configure this item add a section called: /settings/external scripts/alias/alias_file_age
alias_file_age = checkFile2 filter=out "file=$ARG1$" filter-written=>1d MaxWarn=1 MaxCrit=1 "syntax=%filename% %write%"

; alias_file_size - Alias for alias_file_size. To configure this item add a section called: /settings/external scripts/alias/alias_file_size
alias_file_size = CheckFiles "filter=size > $ARG2$" "path=$ARG1$" MaxWarn=1 MaxCrit=1 "syntax=%filename% %size%" max-dir-depth=10

; alias_mem - Alias for alias_mem. To configure this item add a section called: /settings/external scripts/alias/alias_mem
alias_mem = checkMem MaxWarn=80% MaxCrit=90% ShowAll=long type=physical type=virtual type=paged type=page

; alias_process - Alias for alias_process. To configure this item add a section called: /settings/external scripts/alias/alias_process
alias_process = checkProcState "$ARG1$=started"

; alias_process_count - Alias for alias_process_count. To configure this item add a section called: /settings/external scripts/alias/alias_process_count
alias_process_count = checkProcState MaxWarnCount=$ARG2$ MaxCritCount=$ARG3$ "$ARG1$=started"

; alias_process_hung - Alias for alias_process_hung. To configure this item add a section called: /settings/external scripts/alias/alias_process_hung
alias_process_hung = checkProcState MaxWarnCount=1 MaxCritCount=1 "$ARG1$=hung"

; alias_process_stopped - Alias for alias_process_stopped. To configure this item add a section called: /settings/external scripts/alias/alias_process_stopped
alias_process_stopped = checkProcState "$ARG1$=stopped"

; alias_sched_all - Alias for alias_sched_all. To configure this item add a section called: /settings/external scripts/alias/alias_sched_all
alias_sched_all = CheckTaskSched "filter=exit_code ne 0" "syntax=%title%: %exit_code%" warn=>0

; alias_sched_long - Alias for alias_sched_long. To configure this item add a section called: /settings/external scripts/alias/alias_sched_long
alias_sched_long = CheckTaskSched "filter=status = 'running' AND most_recent_run_time < -$ARG1$" "syntax=%title% (%most_recent_run_time%)" warn=>0

; alias_sched_task - Alias for alias_sched_task. To configure this item add a section called: /settings/external scripts/alias/alias_sched_task
alias_sched_task = CheckTaskSched "filter=title eq '$ARG1$' AND exit_code ne 0" "syntax=%title% (%most_recent_run_time%)" warn=>0

; alias_service - Alias for alias_service. To configure this item add a section called: /settings/external scripts/alias/alias_service
alias_service = checkServiceState CheckAll

; alias_service_ex - Alias for alias_service_ex. To configure this item add a section called: /settings/external scripts/alias/alias_service_ex
alias_service_ex = checkServiceState CheckAll "exclude=Net Driver HPZ12" "exclude=Pml Driver HPZ12" exclude=stisvc

; alias_up - Alias for alias_up. To configure this item add a section called: /settings/external scripts/alias/alias_up
alias_up = checkUpTime MinWarn=1d MinWarn=1h

; alias_updates - Alias for alias_updates. To configure this item add a section called: /settings/external scripts/alias/alias_updates
alias_updates = check_updates -warning 0 -critical 0

; alias_volumes - Alias for alias_volumes. To configure this item add a section called: /settings/external scripts/alias/alias_volumes
alias_volumes = CheckDriveSize MinWarn=10% MinCrit=5% CheckAll=volumes FilterType=FIXED

; alias_volumes_loose - Alias for alias_volumes_loose. To configure this item add a section called: /settings/external scripts/alias/alias_volumes_loose
alias_volumes_loose = CheckDriveSize MinWarn=10% MinCrit=5% CheckAll=volumes FilterType=FIXED ignore-unreadable 

; default - Alias for default. To configure this item add a section called: /settings/external scripts/alias/default
default = 

[/settings/external scripts]
allow arguments=true

[/settings/external scripts/scripts]
check_updates=cmd /c echo scripts\Check-Updates.ps1 $ARG1$; exit $LastExitCode | powershell.exe -command -
check_tomcat=cmd /c echo C:\scripts\checktomcat.ps1 $ARG1$ $ARG2$; exit $LastExitCode | powershell.exe -command -

I tried installing 4.4 omg, what a mess.
Not only is the ini file completly different, but almost blank.

Re: Check works on some systems- but not all.

Posted: Tue Jun 20, 2017 4:47 pm
by cdienger
Hi John,

Try adding a timeout line under teh /settings/external scripts section:

[/settings/external scripts]
allow arguments=true
timeout = 300

Restart the nsclient and test again.

You may find https://assets.nagios.com/downloads/nag ... ios-XI.pdf useful for configuring the .4.4 install.

Re: Check works on some systems- but not all.

Posted: Tue Jun 20, 2017 4:54 pm
by JohnFLi
sadly, same result.
not sure if it helps at all, but when I run the powershell script on the server directly, it takes 50 seconds.


[EDIT]

It still gives me the same result when I do it manually from the CLI on the Nagios server.

Code: Select all

./check_nrpe -H g1ppdc02 -t 320 -c check_updates -a 30
CHECK_NRPE: Received 0 bytes from daemon.  Check the remote server logs for error messages.
but in the nagios display......its working fine.
winup.jpg

[Re-Edit]
Well, the machine that is on the top line of the above pic.....went back to the stupid error

Re: Check works on some systems- but not all.

Posted: Wed Jun 21, 2017 10:02 am
by cdienger
A timeout still seems like the problem. Add timeout=300 under [/settings/NRPE/server]:

[settings/NPRE/server]
timeout = 300

Make sure to restart the NSClient service again and let us know.

Have you been able to test with the .4.4 client?

Re: Check works on some systems- but not all.

Posted: Wed Jun 21, 2017 10:44 am
by JohnFLi
so far that is looking good.
Also, in the check command, I changed the -t 120 to -t 300.

Code: Select all

$USER1$/check_nrpe -H $HOSTADDRESS$  -t 300 -c check_updates -a $ARG1$

Re: Check works on some systems- but not all.

Posted: Wed Jun 21, 2017 11:04 am
by cdienger
Glad to hear : ) Keep us posted!

Re: Check works on some systems- but not all.

Posted: Wed Jun 21, 2017 11:12 am
by JohnFLi
Not a problem...... quick side question.....is there a way I can add the check to all my other machinces quickly? or am I going to need add them 1 at a time?