What will probably take you the most time after you have Nagios installed and running is getting all or your devices into the cfg files that Nagios uses.  What I did was wrote two python Scripts that take Excel spreadsheets and creates the cfg files from them.  I have some more things that I want to add into the scripts to handle more configuration options from the spreadsheet, but as it stands they get you up and running rather quickly.

First up is the windows.cfg file script.

The spreadsheet should have the following columns:

Name – short Name for the Server

Alias – long name of the server

IP – IP Address

HostGroup  - what group do you want the server put in?  You can put more than one Group here, just separate them with commas.   The script will create all host groups used in this spreadsheet.

CheckNT – do you want Nagios to check for NSClient++? X for Yes

Uptime – do you want Nagios to retrieve server uptime? X for Yes

CPULoad – do you want Nagios to check the CPU Load? X for Yes

MemUsage – do you want Nagios to check the memory usage? X for Yes

Drives to monitor – Drive letters to monitor disk space on, separate multiple by ;.

MonitorExplorer do you want Nagios to monitor Explorer.exe? X for Yes personally don’t find this useful, but it’s one of the default checks that Nagios gives you.

Parent Device – this is whatever device this server is connected to, this is so that you don’t get alerts on the 12 servers connected to the switch that just powered down that you got an alert for.

Contacts – this allows you to add special contact groups for specific servers in the file. (i.e. notify Security that the Security Camera Server just went offline, or someone that only manages one server can be told that their server is down.) the contact group must already be created, but you can associate them with a device this way.

And now the script:


#=========================================================================
# AUTHOR:  Robert Anderson
# DATE:    6/20/2011
# COMMENT: Creates Nagios switch.cfg file from csv
#
#=========================================================================
import csv

strDate = '2011.06.20'
ArrGroups = ['servers']

#InputFile = open('windows2.csv', 'r\n')
outF = open('windows.cfg.txt', 'w')

#write Some Header information to the Final Config File
outF.write('###############################################################################\n')
outF.write('# windows.CFG\n')
outF.write('#\n')
outF.write('# Last Modified: ' + strDate +'\n')
outF.write('#\n')
outF.write('# NOTES: This config file assumes that you are using the sample configuration\n')
outF.write('#	       files that get installed with the Nagios quickstart guide.\n')
outF.write('#\n')
outF.write('###############################################################################\n')
outF.write('\n')

Devices = csv.reader(open('windows2.csv'))

#Loops through the input file
for Row in Devices:
   strName = Row[0]
   strAlias = Row[1]
   strIP = Row[2]
   strHostGroup = Row[3]
   strCheckNT = Row[4]
   strUptime = Row[5]
   strCPULoad = Row[6]
   strMemUsage = Row[7]
   strDriveSpace = Row[8]
   strProcesses = Row[9]
   strParent = Row[10]
   strContacts = Row[11]

   print 'Creating Host: ' +strName+ '...'

   outF.write('###############################################################################\n')
   outF.write('# ' + strName + '     ---     ' + strAlias+'\n')
   outF.write('###############################################################################\n')
   outF.write('\n')
   outF.write('define host{\n')
   outF.write('  use     generic-switch      ; Inherit default values from a template\n')
   outF.write('  host_name   ' + strName + '     ; The name we\'re giving to this switch\n')
   outF.write('  alias       ' + strAlias + '    ; A longer name associated with the switch\n')
   outF.write('  address     ' + strIP + '       ; IP address of the switch\n')
   outF.write('  hostgroups  windows-servers,' + strHostGroup + '        ; Host groups this switch is associated with\n')
   outF.write('  max_check_attempts  3\n')
   outF.write('  normal_check_interval   2       ; Check the service every 5 minutes normally\n')
   outF.write('  retry_check_interval    1       ; Re-check the service every minute\n')
   outF.write('  notification_interval   10\n')
   if strContacts!='':
       outF.write('  contact_groups      admins,Server,'+strContacts+'\n')
   else:
       outF.write('  contact_groups      admins,Server\n')
   if strParent!='': outF.write('	parents         '+strParent +'\n')
   outF.write('  }\n')
   outF.write('\n')
   outF.write('\n\n')

   if strCheckNT=='X':
        outF.write('define service{\n')
        outF.write('  use         generic-service\n')
        outF.write('  host_name       ' + strName+'\n')
        outF.write('  service_description NSClient++ Version\n')
        outF.write('  check_command       check_nt!CLIENTVERSION\n')
        outF.write('  }\n')

   if strUptime=='X':
        outF.write('define service{\n')
        outF.write('  use         generic-service\n')
        outF.write('  host_name       ' + strName+'\n')
        outF.write('  service_description Uptime\n')
        outF.write('  check_command       check_nt!UPTIME\n')
        outF.write('  }\n')

   if strCPULoad=='X':
        outF.write('define service{\n')
        outF.write('  use         generic-service\n')
        outF.write('  host_name       ' + strName+'\n')
        outF.write('  service_description CPU Load\n')
        outF.write('  check_command       check_nt!CPULOAD!-l 5,80,90\n')
        outF.write('  }\n')

   if strMemUsage=='X':
        outF.write('define service{\n')
        outF.write('  use         generic-service\n')
        outF.write('  host_name       ' + strName+'\n')
        outF.write('  service_description Memory Usage\n')
        outF.write('  check_command       check_nt!MEMUSE!-w 80 -c 90\n')
        outF.write('  }\n')

#if strDriveSpace != '' split on ';' and create a space monitor for each element
   if strDriveSpace!='':
       strDri = strDriveSpace.split(',')
       for Drive in strDri:
           if Drive!=',':
               outF.write('define service{\n')
               outF.write('  use         generic-service\n')
               outF.write('  host_name       ' + strName+'\n')
               outF.write('  service_description '+Drive+':\ Drive Space\n')
               outF.write('  check_command       check_nt!USEDDISKSPACE!-l '+Drive+' -w 80 -c 90\n')
               outF.write('  }\n')

#if strProcesses != '' split on ';' and create a process monitor for each element
   if strProcesses!='':
       strPro = strProcesses.split(',')
       for Process in strPro:
           if Process!=',':
               outF.write('define service{\n')
               outF.write('  use         generic-service\n')
               outF.write('  host_name       ' + strName+'\n')
               outF.write('  service_description '+Process+'\n')
               outF.write('  check_command       check_nt!PROCSTATE!-d SHOWALL -l '+Process+'\n')
               outF.write('  }\n')

   outF.write('\n')
   outF.write('\n')
   outF.write('\n')

   if strHostGroup.find(',')!=-1:
       intGrpFnd = 0
       x = strHostGroup.partition(',')
       for group in x:
           if group != '':
               for exGroup in ArrGroups:
                   if exGroup == group:
                       intGrpFnd = 1
       if intGrpFnd == 0:
           ArrGroups = ArrGroups + [group]
   else:
       intGrpFnd = 0
       for exGroup in ArrGroups:
           if exGroup == strHostGroup:
               intGrpFnd = 1
       if intGrpFnd == 0:
           ArrGroups = ArrGroups + [strHostGroup]

outF.write('###############################################################################\n\n')
outF.write('# Define HostGroups\n\n')
outF.write('###############################################################################\n\n')
outF.write('\n')

for group in ArrGroups:
    if group!='':
        print 'Creating Group: '+group+'...'
        outF.write('define hostgroup{\n')
        outF.write('	hostgroup_name	'+group+'	; The name of the hostgroup\n')
        outF.write('	alias		'+group+'	; Long name of the group\n')
        outF.write('	}\n')
        outF.write('\n')

outF.close()

When you run the script you will get a file windows.cfg.txt as the output.  The one difference between this config and the ones that come with Nagios is that I group host definition and all of its services together.  I did this to make it easier to take out a server later if need be or to find all the monitored services for a specific server.

I could have sworn that i had already posted this but it looks like i didn’t.  I posted the group policy we use to clean up users on our lab/library PCs, but we are actually mostly Mac os x. So I wrote a short bash script that can be sent out to the OS X computers through apple remote desktop.

I will give you the same warning i give my techs before they run this. You are deleting everything saved by any user not explicitly listed with a Username) echo “–saved i$” ;; section. Be 100% sure that no one has saved anything to their desktop or anywhere else in their local profile before running.

I make no claims that the code is pretty, just that it works.

#!/bin/bash

clear
echo "Cleaning up users ...";

cd /Users

for i in *;
do [ -d $i ] &&;
case "$i" in
admin)
echo "-- Saved $i";
;;
Administrator)
echo "-- Saved $i";
;;
Shared)
echo "-- Saved $i";
;;
techstaff)
echo "-- Saved $i";
;;

*)
rm -rf $i
echo "-- Deleted $i";
;;
esac
done

echo "...done";

You’ll need to create a case statement for each of the local accounts that you want to keep.

You can run it a few ways:

  • The quickest would be to copy the script into the unix shell script portion of Apple Remote Desktop and send it to a handful of computers.
  • You can also copy the script to a file and copy it out to all of the computers and then run it.  If the file was called cleanuser.sh and you copied it to /tmp/, you would run these lines through the unix script part of ARD.

chmod +x /tmp/cleanuser.sh
/tmp/cleanuser.sh
  • Least desirable would be to copy the script to a file and then manually run it on each individual computer.  Same two lines from above in terminal will run the script.

Before i started working at my current job, they didn’t have a central person managing the systems and standardizing configuration, which meant it didn’t happen. The Tech personnel at each location would setup the computers however they wanted, which meant that no two computers were setup the same way. The problem with this was that trying to administer these systems now was difficult as no one was ever sure of what the administrator password or account name was. Luckily the building techs use Apple remote desktop regularly and even if they can’t tell you what the password for the computer is, they had added it to their computer list in ARD, which allows us to copy files and run commands on these computers. so i wrote the following script file for the them to copy out and run on their computers to create a TechStaff user, grant it admin privileges and rights to manage the computer over Apple Remote Desktop.

UserFound=$(dscl . -list /Users | Grep techstaff)
UserFound2=$(dscl . -list /Users | Grep techstaff)
if [ "$UserFound" = "" ] && [ "$UserFound2" = "" ]; then
	echo "Create techstaff..."
	#Create a new entry in the local (.) domain under the category /users.
	dscl . -create /Users/techstaff
	#Create and set the shell property to bash.
	dscl . -create /Users/techstaff UserShell /bin/bash
	#Create and set the user’s full name.
	dscl . -create /Users/techstaff RealName "Tech Staff"
	#Create and set the user’s ID.
	dscl . -create /Users/techstaff UniqueID 555
	#Create and set the user’s group ID property.
	dscl . -create /Users/techstaff PrimaryGroupID 1000
	#Create and set the user home directory.
	dscl . -create /Users/techstaff NFSHomeDirectory /Local/Users/techstaff
	#Set the password.
	dscl . -passwd /Users/techstaff MyPassword
	#give User Admin access
	dscl . -append /Groups/admin GroupMembership techstaff
	#Grant User Access through Remote Desktop
	/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -activate -configure -access -on -users techstaff -privs -all
else
	echo "Found techstaff..."
fi

I then had them use the copy function of Apple Remote Desktop to copy this file to /tmp.
Copy File Settings for Apple Remote Desktop

What i had them do was choose all of the computers in their all computers list and choose to copy that file to all of them, knowing that it would fail on the ones that weren’t on, etc. on the results screen for the copy, sort the result column so you have all of the successful computers at the top and choose those. Using the Unix function of Apple Remote Desktop, I had them send the following three lines to those computers as root:

chmod +x /tmp/SCT2.sh
/tmp/SCT2.sh
rm -f /tmp/SCT2.sh

These lines make the script executable (chmod +x /tmp/SCT2.sh), run the script (/tmp/SCT2.sh), and then delete the script (rm -f /tmp/SCT2.sh).

The resulting output from running these lines will be one of two things, either a line saying that it found a techstaff user already on the computer, or a line that it’s creating techstaff and then the results of commands to create the user and give it permissions.

I wrote the following script to search through all of the computers on our network and return who was a member of the local admin group. if it’s a group that is returned, it will give you who is a member of that group.

It takes one file as the input that is a list of computers you want it to contact, i generated most of mine for AD Users & Computers.

The output goes to both the screen and an output file for use later.  i did this so i could see that the script was running, noticed things that look out of place as it goes by, but also have a copy somewhere to refer to later.

Code:

Const ForReading = 1
Const ForAppending = 8
Const ForWriting = 2

On Error Resume Next

Set objShell = CreateObject("Wscript.Shell")

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objInFile = objFSO.OpenTextFile("D:\Rob\Scripts\enumadminusers\others.txt", ForReading)
Set objOutFile = objFSO.OpenTextFile("D:\Rob\Scripts\enumadminusers\Output-Others.txt", ForWriting)

Do Until objInFile.AtEndOfStream
    strLine = objInFile.ReadLine
 	arrItems = Split(strLine, ",")
    strComputer = arrItems(0)
	wscript.echo strComputer & "..."

	if Ping(strComputer) = True then
    		Wscript.Echo "Host " & strComputer & " contacted"
		objOutFile.WriteLine "Host " & strComputer & " contacted"

		Set objGroup = GetObject("WinNT://" & strComputer & "/Administrators,group")
		If Err.Number <> 0 Then
    		Wscript.Echo "Error: " & Err.Number
    		Wscript.Echo "Error (Hex): " & Hex(Err.Number)
    		Wscript.Echo "Source: " &  Err.Source
    		Wscript.Echo "Description: " &  Err.Description
    		Err.Clear
		Else
			Wscript.Echo "Members of local Administrators group on computer " & strComputer
			objOutFile.WriteLine "Members of local Administrators group on computer " & strComputer

			Call EnumGroup(objGroup, "")

			wscript.echo "##############################################################"
			objOutFile.WriteLine "##############################################################"
		End If
	Else
    	Wscript.Echo "Host " & strComputer & " could not be contacted"
		objOutFile.WriteLine "Host " & strComputer & " could not be contacted"
		wscript.echo "##############################################################"
		objOutFile.WriteLine "##############################################################"
	end if
Loop
ObjInFile.Close
objOutFile.Close

Function Ping(strHost)
    dim objPing, objRetStatus

    set objPing = GetObject("winmgmts:{impersonationLevel=impersonate}").ExecQuery _
      ("select * from Win32_PingStatus where address = '" & strHost & "'")

    for each objRetStatus in objPing
        if IsNull(objRetStatus.StatusCode) or objRetStatus.StatusCode<>0 then
		    Ping = False
        else
            Ping = True
        end if
    next
End Function 

Sub EnumGroup(objGroup, strOffset)
	Dim objMember
	For Each objMember In objGroup.Members
		Wscript.Echo strOffset & objMember.Name & " (" & objMember.Class &")"
		objOutFile.WriteLine strOffset & objMember.Name & " (" & objMember.Class &")"
		If (objMember.Class = "Group") Then
			Call EnumGroup(objMember, strOffset & "--")
		End If
	Next
End Sub

Some of the Students had started bringing in a N64 emulator that they were storing in their network folders to use throughout the day.  This was against our policy and i was asked to gather information about who had it, etc.  we could have used windows search on the server to find this, but i decided to come up with a script that i could schedule to run at night to give me a listing of and file type that i wanted (exe, mp3, zip, bat,…).   so i wrote this script and tried to make it easily modified to handle different situations.

' ***************************************************************************
'    File Server Search Script
'    Created by Robert Anderson
'    2010.02.22
'
'    Looks through a given path and it's subdirectories for a given file type
'    and outputs it's findings to a csv file for use in Excel
' ***************************************************************************

on error resume next
'Create Variables used throughout the script
Dim objFSO, objFolder, colFiles, objSubFolder, objSubFile, objFile
Dim strUser, strLocLen, strFolderLen, strLoc, strFNameLen, strLastLoc
Dim strFolder, strExt
Const ForWriting = 2

'initialize values for some variables
strUser = ""                            'User's Name
strLastLoc = ""                            'File Location
strFolder = "E:\HighSchool\Students"    'root for scanning from
strExt = "exe"                            'File Extension we're looking for

'create the FSO objests for the directory and for the output file
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(strFolder)
Set colFiles = objFolder.Files
Set objFileOut = objFSO.OpenTextFile("e:\searchlog.csv", ForWriting)

'csv file header line
objFileOut.WriteLine "User,Location,FileName"

For Each File in colFiles
set objFile = objFSO.GetFile(strFolder &amp; "\" &amp; File.Name)
If Err.Number &lt;&gt; 0 Then
Wscript.Echo "Error: " &amp; Err.Number
Wscript.Echo "Description: " &amp;  Err.Description
Wscript.Echo "Source: " &amp;  Err.Source
Err.Clear
End If
Next

ScanSubFolders(objFolder)

'Error information if encountered
If Err.Number &lt;&gt; 0 Then
Wscript.Echo "Error: " &amp; Err.Number
Wscript.Echo "Description: " &amp;  Err.Description
Wscript.Echo "Source: " &amp;  Err.Source
Err.Clear
End If

Sub ScanSubFolders(objFolder)

Set colFolders = objFolder.SubFolders

For Each objSubFolder In colFolders
Set colFiles = objSubFolder.Files
For Each objFile in Colfiles
If lcase(right(objFile.Name,3)) = strExt Then
'break apart directory path to get User's Name
StuDir=split(objfile, "\")
'gets the location minus the file name
strFNameLen = len(objFile.Name)
strLocLen = len(objFile)
strFolderLen = strLocLen - strFNameLen
strLoc = left(ObjFile, strFolderLen)
'set User's Name from Directory path
If strUser &lt;&gt; StuDir(3) Then
strUser=StuDir(3)
End If
'File Location
If strLastLoc &lt;&gt; strLoc Then
strLastLoc = strLoc
End If
'print out the username, location of file, and file name
objFileOut.WriteLine strUser &amp; "," &amp; StrLastLoc &amp; "," &amp; objFile.Name
wscript.echo "."    'printed so we see progress
End If
Next
ScanSubFolders(objSubFolder)
Next
End Sub

objFileOut.Close

what i did then was to schedule a task to run this once a week.  When scheduling the script to run, you don’t choose the script, but rather cscript yourscript.vbs.  I could then use the spread sheet to filter for a particular user and or a particular file name.

© 2013 Suffusion theme by Sayontan Sinha