Nagios Windows Updates check

Following on from my post last night about the Windows Updates check on MonitoringExchange a colleague reminded me that we acutally modified the script from there as we weren’t looking for the names of updates to be listed but simply to get the total number of updates that are outstanding. The modified version of the script is listed below for reference and the source for this is at the following URL: https://www.monitoringexchange.org/inventory/Check-Plugins/Operating-Systems/Windows-NRPE/Check-Windows-Updates

<job>
  <script language="VBScript">
    ' Parse command line switches for pending updates
    If Wscript.Arguments.Named.Exists("h") Then
      Wscript.Echo "Usage: check_win_updates.wsf /w:1 /c:2"
      Wscript.Echo "/w: - number of updates before warning status "
      Wscript.Echo "/c: - number of updates before critical status "
    End If
    If Wscript.Arguments.Named.Exists("w") Then
      intWarning = Cint(Wscript.Arguments.Named("w"))
    Else
      intWarning = 0
    End If
    If Wscript.Arguments.Named.Exists("c") Then
      intCritical = Cint(Wscript.Arguments.Named("c"))
    Else
      intCritical = 0
    End If
    Set objShell = CreateObject("WScript.Shell")
    Dim sysroot
    sysroot = objShell.ExpandEnvironmentStrings("%systemroot%")
    ' Check if the Server is pending a reboot and quit with warning
    Set objSysInfo = CreateObject("Microsoft.Update.SystemInfo")
    If objSysInfo.RebootRequired Then
      Wscript.Echo "Warning: Reboot required | updates=-1"
      Wscript.quit(1)
    End If
    ' Dump Software Dist Event log to variable for parsing
    Set objExec = objShell.Exec("cmd.exe /c type " & sysroot & "SoftwareDistributionReportingEvents.log")
    results = LCase(objExec.StdOut.ReadAll)
    res_split = Split(results, vbCrLf)
    Dim regEx
    Set regEx = New RegExp
    regEx.Pattern = "(.)S*s*S*s*S*s*ds*(d*)s*S*s*S*[0-9s]*S*s*S*s*.*t(.*)"
    regEx.IgnoreCase = true
    count = 1
    ReDim arrDyn(1)
    For Each zeile in res_split
      firstsign = regEx.Replace(zeile, "$1")
      If (firstsign = "{") Then
                number = regEx.Replace(zeile, "$2")
        finish = regEx.Replace(zeile, "$3")
                If (number = 147) Then
          count = count + 1
          ReDim Preserve arrDyn(count + 1)
                  arrDyn(count + 1) = finish
        End If
      End If
    Next
    mount_updates = -1
    For x = 0 to UBound(arrDyn)
      If x = UBound(arrDyn) Then
                      end_array = Split(arrDyn(x), " ")
                      mount_updates = end_array(UBound(end_array) - 1)
      End If
    Next
    ' Quit the script with the appropriate performance data
    mount_updates = Cint(mount_updates)
    If mount_updates = 0 Then
      Wscript.Echo "OK: There are no pending updates | updates=0"
      Wscript.Quit(0)
    ElseIf mount_updates >= intCritical Then
      Wscript.Echo "Critical: There are " & mount_updates & " updates pending | updates=" & mount_updates
      Wscript.Quit(2)
    ElseIf mount_updates >= intWarning Then
      Wscript.Echo "Warning: There are " & mount_updates & " updates pending | updates=" & mount_updates
      Wscript.Quit(1)
    ElseIf mount_updates < intWarning Then
      Wscript.Echo "OK: There are " & mount_updates & " updates pending | updates=" & mount_updates
      Wscript.Quit(0)
    Else
      Wscript.Echo "Unknown: There has been an error"
      Wscript.Quit(3)
    End If
    Wscript.Echo "Unknown: There has been an error"
    Wscript.Quit(3)
  </script>
</job>

NSClient 0.3.9 released

NSClient 0.3.9 was released earlier this month and from the looks of the change log should be a good replacement for 0.3.8. (http://www.nsclient.org/nscp/blog/Blog-2011-07-05). As with previous releases there are both 32-bit and 64-bit variants and the option for an MSI package or for a ZIP download.

Some things I have noticed in the new release (these may have been in 0.3.8 but I never noticed them) are two new external scripts to check Printer status and check Windows Updates. I have been using my own Windows Update script (https://www.monitoringexchange.org/inventory/Check-Plugins/Operating-Systems/Windows-NRPE/Check-Windows-Updates) as I found the ones that query WMI take longer than the default 10 seconds for the script to run without timing out. Giving the bundled script a go it did a good job of outputting some useful information about the Windows Updates however it still took too long to run so I doubt that I will be using this in its current form. The output when running it on my workstation is as follows:

OK: Number of critical updates not installed: 1 <br />Number of software updates not installed: 6 <br /> Critical updates name: Service Pack 1 for Microsoft Office 2010 (KB2510690) 32-bit Edition+

The Printer check also ran through my list of installed printers and came out with an “Unknown” status and the details listed didnt match what Windows was saying so again probably wont be using this in its current format and more likely monitor the printers individually with SNMP based checks directly to the printers.

There are some good additions to the list of modules. CheckTaskSched looks to be a good addition to make sure that those scheduled tasks you have left to run on your server are running as expected and not left stuck in a running state (or didn’t exit with error code 0). CheckFile and CheckFile2 have been amalgamated into the CheckFiles module which will allow you to check a single file but also multiple files for certain criteria. The link above gives examples on checking file versions, line counts, file sizes etc.

For a full list of changes the change log can be found here: http://www.nsclient.org/nscp/blog/Blog-2011-07-05

RSA Authentication Manager SQL bug

As part of a planned reboot of our client’s infrastructure last month we had an issue with the RSA server taking a *LONG* time to come back up (were talking hours not minutes). After logging a call with RSA they pointed out that Authentication Manager 7.1 has an issue with cleaning up the .sql files it creates as part of its standard operation and this has been resolved in SP4.

The .sql files that are generated are all saved in C:WindowsTemp and are in the format DbMgmtSqlScript*.sql with 1 or two generated per minute on the server. The content of the files is as follows

select to_char(count(*)) from dba_tablespaces;

QUIT;

Whilst waiting for approval to install SP4 on the server I was looking for a fix as the RSA server has generated over 64,000 files this month and I stumbled across the following article (http://microsoftplatform.blogspot.com/2011/04/rsa-authentication-manager-71-bug.html) which describes a nice batch file that can be used to clear out the .sql files on a daily basis:

del c:/windows/temp/dbmgmt*.sql

That should carry out a workaround for the short term. Long term I would recommend that you install SP4 and Patch 4 which can be downloaded from the RSA website.

CheckPoint Full Disk Encryption and RSA SecurID800

I have spent the past week looking at a peculiar issue with CheckPoint Full Disk Encryption for a client. As a bit of a background all laptops are encrypted with Full Disk Encryption and to provide two factor authentication we are using the RSA SecurID800 which acts as a Smart Card as well as a one time authenticator.

Whilst provisioning a laptop for a new starter we re-used an existing token, issued the Smart Card certificate from our internal Certification Authority and it was added to the token successfully. After updating Full Disk Encryption from the MI Console we rebooted and tested login. Everything worked fine.

The issues came when we removed the old certificates from the token and suddenly Full Disk Encryption was showing “Invalid Logon – No certificates were found on this token” yet when in Windows the RSA software shows the certificate is there and the fingerprint matches what was picked up from Active Directory by the MI Console. Rebooted the laptop and still the same no certificates error.

Speaking with CheckPoint on the issue didn’t turn up much so I decided to issue a new certificate and try again. Went through the same process and upon reboot it worked fine and I put the original error down to a glitch so went and removed the old token from the SID800. Rebooted and it was broken again with the same error message.

To fix the issue I removed *all* certificates from the token, revoked all the issued ones in the CA and then issued one more for the user. All works fine and the user can now work on the laptop without issue.

Moral of the story… Remove all certificates first and then only add the one that you need. Its easier in the long run

Roxio Drag2Disk global uninstall

I had an issue with one of my clients this week and slow workstation start up times. Looking through the items that were running for all users at login was Roxio Drag2Disk as someone had not taken it out of the standard software image. The client didn’t use or need the software so I looked at a way to uninstall the various components without having to visit each machine individually (Yes we will be removing it from the image).

I thought it would be useful to get the script out there in case others need to accomplish the same task. If you want to use it just dump it somewhere central on your network (eg NETLOGON) and then run it as a startup script in a Group Policy Object

Script is below

' Script: uninstall_roxio.vbs
' Author: Matt White
' Version: 1.0
' Date: 15-06-2011
' Details: Uninstall all Roxio components from a workstation
' Usage: Run as a startup script GPO linked to the relevant Computers OU

'On Error Resume Next

' Define any Variables
dim arrRoxioGUIDS, arrRoxioNames
Set objShell = Wscript.CreateObject("Wscript.Shell")
Set objFSO = Wscript.CreateObject("Scripting.FileSystemObject")
Const ForReading = 1, ForWriting = 2, ForAppending = 8

' Define Application GUIDS
arrRoxioGUIDs = Array("{30465B6C-B53F-49A1-9EBA-A3F187AD502E}", _
"{0D397393-9B50-4c52-84D5-77E344289F87}", _
"{2F4C24E6-CBD4-4AAC-B56F-C9FD44DE5668}", _
"{619CDD8A-14B6-43a1-AB6C-0F4EE48CE048}", _
"{6675CA7F-E51B-4F6A-99D4-F8F0124C6EAA}", _
"{83FFCFC7-88C6-41c6-8752-958A45325C82}", _
"{C8B0680B-CDAE-4809-9F91-387B6DE00F7C}", _
"{0394CDC8-FABD-4ed8-B104-03393876DFDF}")
arrRoxioNames = Array("RoxioUpdateManager", _
"RoxioCreatorData", _
"RoxioDragToDisk", _
"RoxioCreatorCopy", _
"RoxioExpressLabeler", _
"RoxioCreatorAudio", _
"RoxioCreatorDE", _
"RoxioCreatorTools")

' Create Check if log file exists, if not create it
if objFSO.FileExists("C:roxiouninstall.log") Then
Wscript.Echo "File Exists"
Set objLogFile = objFSO.OpenTextFile("C:roxiouninstall.log", ForAppending)
Else
Wscript.Echo "Creating file"
Set objNewLogFile = objFSO.CreateTextFile("C:roxiouninstall.log")
objNewLogFile.Close
Set objLogFile = objFSO.OpenTextFile("C:roxiouninstall.log", ForAppending)
End If

objLogFile.WriteLine "Uninstall of all Roxio components started " & Now
Wscript.Quit
' Uninstall Each component
For i = 0 to UBound(arrRoxioNames)
' Check if component is installed
If RegKeyExists("HKLM", "SOFTWAREMicrosoftWindowsCurrentVersionUninstall" & arrRoxioGUIDs(i),"UninstallString") = "True" Then
objLogFile.WriteLine "Uninstalling " & arrRoxioNames(i)
objShell.Run "cmd /c msiexec.exe /x " & arrRoxioGUIDs(i) & " /quiet",0,True
If RegKeyExists("HKLM", "SOFTWAREMicrosoftWindowsCurrentVersionUninstall" & arrRoxioGUIDs(i),"UninstallString") = "True" Then
objLogFile.WriteLine "Error uninstalling: " & arrRoxioNames(i)
Else
objLogFile.WriteLine "Success uninstalling: " & arrRoxioNames(i)
End If
Else
objLogFile.WriteLine("Error Uninstalling: " & arrRoxioNames(i) & " could not detect installed version.")
End If
Next

' Close Log File
objLogFile.Close

' Function to check if registry key exists
Function RegKeyExists(nHive, strPath, strValueName)
Select Case Left(nHive, 20)
Case "HKCR", "HKEY_CLASSES_ROOT"
nHive = &H80000000
Case "HKCU", "HKEY_CURRENT_USER"
nHive = &H80000001
Case "HKLM", "HKEY_LOCAL_MACHINE"
nHive = &H80000002
Case "HKU", "HKEY_USERS"
nHive = &H80000003
Case "HKCC", "HKEY_CURRENT_CONFIG"
nHive = &H80000005
Case Else
WScript.Echo "Hive Not Supported."
WScript.Quit
End Select
Dim objRegistry
Dim strComputer, strValue

strComputer = "."
Set objRegistry = GetObject("winmgmts:\" & strComputer & "rootdefault:StdRegProv")

objRegistry.GetStringValue nHive, strPath, strValueName, strValue
RegKeyExists = Not IsNull(strValue)
RegKeyExists = CStr (RegKeyExists)
End Function

World IPv6 day got me thinking…

… and playing with IPv6 at home and I now have a partial setup of IPv6 on my home network and my parents will be going fully IPv6 from the weekend 🙂

The issues I had to overcome were firstly part of my own stupidity and then part of a need to understand how IPv6 works. First of all my ISP (BeThere) doesn’t currently support Native IPv6 on their DSL connections so I needed to get an IPv6 tunnel and Hurricane Electric’s Tunnel Broker service (http://www.tunnelbroker.net) came in very handy here as it allowed me to have a public /64 and private /48 address range which seems like a whole load of addresses that I can play with.

To get the firewall configured they actually give you a predefined sample config based on your IPv6 allocation which needed a bit of modifying to work with the setup on my firewall. The trouble was adding the /48 range to the Trust/Internal side of my network. I had configured Router Advertisement and also set the interface to be in Router mode instead of Host mode but my PC wasn’t getting anything other than the link local fe80:: address.

Following some hair pulling and discussion with a colleague I realised the issue was that the link from my PC to the firewall had a device in between that wasn’t IPv6 enabled. I should point out here that the PC and firewall are in different rooms and because its a rented property I am unable to run a nice CAT6 cable between the two. So I improvised and took and old laptop which I wasn’t using and plugged this into the PC, connected the Wireless on the laptop to my network and bridged the two connections. This works great (for the most part) with IPv4 but was unable to bridge any of the IPv6 traffic on the network.

I added the IPv6 stack to the Windows XP machine and this broke the IPv4 bridge and I lost my Internet connection and ability to communicate with the world. A swift disabling of the IPv6 brought this back and I am going to have to resort to buying a Wireless PCI card for my PC.

Undeterred by this minor setback I looked at what other devices were on my network that I could setup IPv6 with that don’t have the same issue. I am running a number of test VMs in an ESXi lab and there is a Ubuntu server and a number of Windows Server 2003 boxes running on here. Starting with the Win2K3 box I added the IPv6 stack to the network card and the server got an IP from the /48 I had been allocated. All I had to do was manually set the DNS servers using the Open DNS IPv6 DNS Sandbox and I was online.

After the success of Server 2003 working I logged into my Ubuntu 10.04 LTS server and ifconfig showed that it had automatically picked up an address from my router. All that was left for me to do was to add the Open DNS entries to my /etc/resolv.conf and I was good to go.

IPv6 works and is clearly the way forward. What I now need to do is to fully understand the address assignment and subnetting so that I can allocate networks more clearly and understand what is happening 🙂

If you want to learn more about IP addressing then take a look at the following page from RIPE (http://www.ripe.net/internet-coordination/press-centre/understanding-ip-addressing) or alternatively the Wikipedia page on IPv6 (http://en.wikipedia.org/wiki/IPv6)

Multiple Juniper SSG clusters on same network

I ran into an issue recently with a client where we were seeing a large level of packet loss to their newly installed SSG140 cluster. There were three clients sharing the same 100Mbit Internet circuit and they all connected directly into a pair of Juniper SRX210 routers.

All three clients had a firewall cluster which was either made up of a pair of Juniper SSG 140s or Juniper SSG 5s and we were seeing the packet loss on the two SSG 140 clusters.

After some investigation and troubleshooting the following KB article from the Juniper website seemed to demonstrate what the problem was: http://kb.juniper.net/InfoCenter/index?page=content&id=KB7435

The virtual MAC address for both firewall clusters public facing interfaces were the same.

Resolution? Rebuild one of the clusters to use a different cluster ID and the MAC address generated for the firewalls is different.

Adobe Reader X Protected Mode

I started to deploy Adobe Reader X to one of my clients the other day and found that users were unable to open files on shared drives mapped to our DFS. Searching through the web I found the following KB article from Adobe (http://kb2.adobe.com/cps/860/cpsid_86063.html)

Cannot open PDF files whose source is DFS or NFS: PDF files in shared locations on a distributed  or networked file system (DFS/NFS) cannot be opened. Attempting to open such a file results in an error opening this document. Access denied.”

Initially I thought I would have to remove Adobe from all the workstations however a quick look in the registry found the place where this has been set – HKEY_CURRENT_USERSoftwareAdobeAcrobat Reader10.0Privileged. To get around the problem I added the following to my login script to force the “bProtectedMode” value to 0

reg add “HKCUSoftwareAdobeAcrobat Reader10.0Privileged” /v bProtectedMode /t REG_DWORD /d 0 /f

This is definitely one to watch out for if rolling out Adobe Reader via GPO.

Opsview: Host Attributes and Keywords

Having been an avid Nagios/Opsview user for a while I am always keen to see new features that make my life of defining and managing systems easier. I had been meaning to try out the host attributes feature of Opsview for a while to redefine the way I monitor various “generic” features on my infrastructure. Up until now I have had to create an exception for a host that I want to monitor in a slightly different way and remembering what did/didnt have exceptions was never the easiest thing to do.

This has all changed with the Host Attributes feature in Opsview. I can now define a single service check that will take a number of values (currently Opsview 3.7.2 will only let you define one however looking at the SQL database there is capacity for 9 arguments. A forum post from Ton Voon has revealed a patch to the host-attributes tab that allows you to define 4 attributes which should be released in an upcoming release – 3.7.3 maybe). This means that I can define a host attribute (e.g. DISK) and then set in this the partition/disk name and the warning/critical values in different arguments to make sure that I can reduce the number of custom service checks or exceptions that I need to define.

I have managed to abstract my Disk space checks and also some checks for Exchange Information Store sizes across my organisation. I plan to try and further abstract other generalised items of monitoring (e.g. Windows Services, Performance counters etc).

Once I had created these checks I needed to add in a viewport to display the status of my Information Stores. In the past this used to be setup individually on each host and service check manually. In the latest release its possible to create a new keyword and then add in the host/services that you want from the Keywords tab. This has made the process of making new views/displays easier and made the monitoring much simpler.

When I get some time I will put up some pictures to go with this article and expand on my ability to monitor network interfaces with the latest version of Opsview.