Nagios Check for Windows Updates

My colleagues have been getting a little frustrated by the “Plugin Timeout” messages in Nagios resulting from the length of time it takes to check for Windows Updates. I had been using Jules Check for Windows Updates  that essentially boils down to calling:

$updateSession = new-object -com "Microsoft.Update.Session"
$updates=$updateSession.CreateupdateSearcher().Search(("IsInstalled=0 and Type='Software'")).Updates

So I took Jules’ work and divided the powershell script into two. One script is called on a scheduled basis (say every 30mins) and writes the result to a text file. When Nagios runs the check for windows updates it calls the other script that parses the output of the text file rather than running a new update session object (the time-consuming bit).

So create the two files. I created them in C:\scripts:

  • check_windows_updates_scheduled.ps1
  • check_windows_updates.ps1

Use the following code:

check_win_updates_scheduled.ps1

# ###########################################################
# check_win_updates_scheduled.ps1 by Jonny McCullagh 20140109
# This powershell script should be called as a scheduled task
# Output is sent to a text file. The text file is then read by
# check_win_updates.ps1
# to answer the nagios call. This saves waiting for the slow
# windows update check.
# Only required change is the path to the temp file below
# ###########################################################
$strPathToTempFile="c:\scripts\check_win_updates.txt"
$countHidden=0
$countCritical=0
$countOptional=0
# ###########################################################
# Check if installed updates require a reboot first
# ###########################################################
if (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired"){
$strOutput = "Updates installed, Reboot required"
Out-File -filepath $strPathToTempFile -inputobject $strOutput
exit 0
}
# ###########################################################
# Perform the actual update lookup
# ###########################################################
$updateSession = new-object -com "Microsoft.Update.Session"
$updates=$updateSession.CreateupdateSearcher().Search(("IsInstalled=0 and Type='Software'")).Updates
# ###########################################################
# Loop through each update to count each type of update
# ###########################################################
foreach($update in $updates) {
if ($update.IsHidden) {
$countHidden++
}elseif($update.AutoSelectOnWebSites) {
$criticalTitles += $update.Title + " "
$countCritical++
}else{
$countOptional++
}
}
# ###########################################################
# Create some strings ready to write out to the output file
# ###########################################################
$strHiddenText="$countHidden Hidden";
$strCriticalText="$countCritical Critical";
$strOptionalText="$countOptional Optional";
# ###########################################################
# Write a string to the output file to be read by check_win_updates.ps1
# ###########################################################
$strOutput = "$strCriticalText $strOptionalText $strHiddenText"
Out-File -filepath $strPathToTempFile -inputobject $strOutput

check_windows_updates.ps1

# ###########################################################
# check_win_updates.ps1 by Jonny McCullagh 20140109
# This powershell script should be called by Nagios and will
# warn if windows updates are available but based on the 
# text output from another powershell script 
# (check_win_updates_available.ps1)
# that runs as a scheduled task
# Only required change is the path to the temp file below
# ###########################################################
$strPathToTempFile="c:\scripts\check_win_updates.txt"
$countHidden=0
$countCritical=0
$countOptional=0
# ###########################################################
# Get the output from the scheduled task and see if any 
# updates are available
# ###########################################################
if (!(Test-Path $strPathToTempFile)) {
	Write-Host "Input file not available. Has scheduled task run check_win_updates_scheduled.ps1"
	exit 2
}
$strInput = Get-Content $strPathToTempFile 
$arrInput = $strInput.split(" ")
$numCritical=$arrInput[0]
$numOptional=$arrInput[2]
$numHidden=$arrInput[4]
# ###########################################################
# Write out the results based on the number of updates
# ###########################################################
if($numOptional -eq "Reboot"){
	write-host "WARNING "$strInput
	exit 1
}elseif($numCritical -gt 0){
	write-host "CRITICAL Updates Available"$strInput
	exit 2
}elseif($numOptional -gt 0){
	write-host "WARNING Updates Available"$strInput
	exit 1
}elseif($numHidden -gt 0){
	write-host "OK Only Hidden Updates Available "$strInput
	exit 0
}else{
	write-host "OK  No Windows Updates "$strInput
	exit 0
}

Add the following to your nsclient.ini

[/settings/external scripts/scripts]
windows_updates=cmd /c echo C:\scripts\check_win_updates.ps1; exit $LastExitCode | powershell.exe -command -
Windows 2008 Scheduled Task

And that can be called with the following in the Nagios commands.cfg :

define command {
command_name    check_windows_updates
command_line    $USER1$/check_nrpe -H $HOSTADDRESS$ -c windows_updates -t 120
}

 

Create the Scheduled Task for check_windows_updates_scheduled.ps1

Choose ‘Create Task’

Windows 2008 Scheduled Task

Give your Task a name and description and ensure it runs as a user with sufficient privileges:Windows 2008 Scheduled Task

Under the Trigger tab choose a schedule of say 30 minutes:Windows 2008 Scheduled Task

For the Action tab choose ‘Start a Program’  and enter the following text in the script field:

C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe “& ‘c:\scripts\check_windows_updates_scheduled.ps1′”

Windows 2008 Scheduled Task

After saving you should have a Scheduled Task similar to the one below.Windows 2008 Scheduled Task

Hopefully you’ll end up with something similar to this: Nagios

6 Responses to “Nagios Check for Windows Updates”

  1. Jason

    Hi Jonny, I have been trying to get windows updates checks on nagios for a month before giving up and by chance I came across this post on google. After using your recommendation for jules’ Check Windows Updates using Powershell script I had the checking working in 5 minutes. I don’t have timeout issues, yet, if I do I will take your suggestion for dumping the report to a log file. Thank you!!

    Reply
    • bbenji63

      good work, i just add some things to work…

      1 – A command line to launch the task with the correct execution policy and spaces in the path
      PowerShell -NoProfile -ExecutionPolicy Bypass -Command “& ‘C:\Program Files\NSClient++\scripts\check_win_updates_scheduled.ps1′”

      2 – A function that return the script path to create the text file
      function Get-ScriptDirectory
      {
      $Invocation = (Get-Variable MyInvocation -Scope 1).Value
      Split-Path $Invocation.MyCommand.Path
      }

      then modify script like this, sorry i don’t know how to do this in one line but it works !
      $strPathToTempFile=Get-ScriptDirectory
      $strPathToTempFile+=”\check_win_updates.txt”

      thanks

      Reply
  2. Ronald

    Hello i got one issue with the scripts. It find on one server 1 optional update. The other original script does not find anyhing. Also the windows update dialog finds nothing. Do you know how the fix that?

    Reply
  3. Kendall

    Thanks for this; I needed a ‘distributed’ Windows Updates check and this is what I have been deploying on my servers to replace the previous method I used which was on-demand from Nagios and would often time out.
    It works well except for a few servers where I have the same issue as Ronald above, i.e. 1 optional update but nothing seems available. What I did find, is if I run the scheduled script manually, it returns 0 for optional updates but when run by Task Scheduler it returns 1 optional… which is bizarre but could be related to permissions so I will investigate that further.

    Reply
  4. Kendall

    UPDATE to above comment: Issue sorted. I needed to check the box in the Scheduled Task “Run with highest privileges”.
    Again, thanks for this post!

    Reply

Leave a Reply

  • (will not be published)

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>