Nagios for Windows is a popular monitoring tool. In this post you’ll learn how to automatically update the host configuration file by using PowerShell to query Active Directory.

Nagios host file configuration is straightforward but tedious to maintain, especially if you have to do so manually for a large number of monitored hosts. If many of your monitored hosts are connected to an Active Directory domain you can use PowerShell to query Active Directory, generate a list of computers, and automatically update your hosts configuration file accordingly. If you schedule this PowerShell script, the result will be an automated and up-to-date host configuration file generation process, which is sure to save any administrator time.

Querying Active Directory to obtain a list of computers in a container ^

PowerShell provides some very convenient hooks to quickly query Active Directory objects. The [adsisearcher] type offers a performance-optimized, general-purpose means of querying objects within particular containers and by filtering by object properties as well as a query string. All you need to use [adsisearcher] is the following syntax:

$searcher = [adsisearcher]""

This will generate a new [adsisearcher] type with no parameters. Some useful options for our example include specifying a container, filter criteria for finding hosts, and actually performing the search. To specify a container, you simply set $searcher.SearchRoot; in this example we have set the container as the Accounting OU in domain.company.com.

$searcher.SearchRoot = [adsi]"LDAP://ou=accounting,dc=domain,dc=company,dc=com"

You will also need to specify that you want to find computers only by setting the filter string (note that you can also do this in the constructor). In this case, we want only computers:

$searcher.Filter = "objectCategory=computer"

Finally, we want to execute the search to find all matching objects (computers) using FindAll:

$adComputers = $searcher.FindAll()

We now have a list of AD computers in the specified container stored in the $adComputers variable. Our next task is to write a function that takes a computer as an input and outputs a string of formatted Nagios configuration goodness.

Outputting Nagios host configuration to a string type ^

We basically want to create a function that accepts a single argument, $computer, builds a string by inserting some of the $computer fields, and then outputs the formatted string. First, we can set up the skeleton of the function:

function adcomputer_to_string() {

Param([SearchResult] $myComputer)

$retString = ""

if ($true) {

// format $retString as needed

}

return $retString

}

A minimal Nagios host configuration requires the following format:

define host {

host_name = (hostname)

alias = (friendlyname)

address = (IPaddress)

max_check_attempts = 3

check_period = 24x7

contact_groups = domain_admins

notification_interval = 30

notification_period = 24x7

}

We will be replacing the items in parentheses with values obtained from querying AD. So, let’s replace the commented-out portion inside the conditional with the following (note that you must define $tab = " " somewhere before this subroutine):

$retString += "define host {`n"

$retString += $tab + "host_name = " + $myComputer.properties.dnshostname + "`n"

$retString += $tab + "alias = " + $myComputer.properties.displayname + "`n"

$retString += $tab + "address = " + [System.Net.Dns]::GetHostAddresses($myComputer.properties.dnshostname) + "`n"

$retString += $tab + "max_check_attempts = 3`n"

$retString += $tab + "check_period = 24x7`n"

$retString += $tab + "contact_groups = domain_admins`n"

$retString += $tab + "notification_interval = 30`n"

$retString += $tab + "notification_period = 24x7`n"

$retString += "}`n`n"

Notice that $myComputer.properties stores a dictionary of properties related to the search result for computer. If you are interested in which properties are available you can print them to the console in a PowerShell session. In general, most of the properties available in Active Directory are available to the PowerShell FindAll() command.

Finally, we might want to do some pre-flight checking before we actually start writing to $retString. We may want to just make sure that the dnshostname property actually exists. To ensure this, we can replace $true in the conditional with:

if ($myComputer.properties.dnshostname)

This will ensure that at least a hostname exists before we try to look it up and get an IP address for the hostname.

Putting it all together ^

We will want to iterate over $adComputers to append a string with the result of adcomputer_to_string([SearchResult] $computer). You can output this to a new hosts.cfg file or append your existing file with the result. You may want to follow something like this:

$tab = " "

function adcomputer_to_string() {

Param($myComputer)

$retString = ""

if ($myComputer.properties.dnshostname) {

$retString += "define host {`n"

$retString += $tab + "host_name = " + $myComputer.properties.dnshostname + "`n"

$retString += $tab + "alias = " + $myComputer.properties.displayname + "`n"

$retString += $tab + "address = " + [System.Net.Dns]::GetHostAddresses($myComputer.properties.dnshostname) + "`n"

$retString += $tab + "max_check_attempts = 3`n"

$retString += $tab + "check_period = 24x7`n"

$retString += $tab + "contact_groups = domain_admins`n"

$retString += $tab + "notification_interval = 30`n"

$retString += $tab + "notification_period = 24x7`n"

$retString += "}`n`n"

}

return $retString

}

$searcher = [adsisearcher]""

$searcher.SearchRoot = [adsi]"LDAP://ou=accounting,dc=domain,dc=company,dc=com"

$searcher.Filter = "objectCategory=computer"

$adComputers = $searcher.FindAll()

$hostsString = ""

foreach ($myComputer in $adComputers) {

$hostsString += adcomputer_to_string($myComputer)

}

$hostsString | Out-File -encoding Unicode "C:\temp_folder\hosts1.cfg"

A word of caution ^

This script is most certainly not production-ready. It is intended to get you started in creating your own Nagios hostfile creation automation script. For example, we don’t do a good job of handling what happens when IP address lookup fails - in these cases, the entry will just be left blank, which will cause Nagios to not read the host file correctly. In addition, we could use additional data points from Active Directory to customize the value of host properties like "contact" (in case we want computer-specific contact customization). Finally, you will have to find your own way of incorporating the output of this script into your Nagios config files. My recommendation would be to include this script’s output file in a containing (manually-managed) hosts configuration file.

Moving forward ^

Your next steps should be to customize this script to match the needs of your Nagios and domain, then to look at how you can configure host-groups based on OU containers and other filters applied while querying Active Directory.

1 Comment
  1. Geoff Kendal 10 years ago

    Excellent idea – I love it!

    You could also create service checks based on what roles are installed on each server with another script!

Leave a reply

Your email address will not be published.

*

© 4sysops 2006 - 2022

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account