Nagios: monitor Active Directory accounts

Check for Active Directory Accounts using powershell through NRPE / nsclient++:

  • Account Disabled
  • Account Expired
  • Account Expiring
  • Account Inactive
  • Locked Out
  • Password Expired
  • Password Never Expires

I am using nsclient++ on servers to execute PowerShell scripts & co. The flow is:

Nagios => check_nrpe =>  powershell script => nagios feedback

I am using the standard ActiveDirectory PowerShell module. This works also on Server Core.

tested setup

Linux:

  • Centos 6.4 x64
  • Nagios 3.4.4
  • check_nrpe 2.13
  • Centreon 2.4.2

Active Directory:

  • Windows Server 2008 R2 / Windows Server 2012
  • nsclient++ 0.4.1 x64
  • Core & GUI Servers

Script args

  • action (LockedOut by default)
  • searchBase (Whole domain by default)
  • seachScope (subtree by default)
  • maxWarn (warning if above)
  • maxCrit (Critical if above)

action can be:
AccountDisabled,AccountExpired,AccountExpiring,AccountInactive,LockedOut,PasswordExpired,PasswordNeverExpires
LockedOut if omitted

searchBase can be:
dc=mydomain,dc=com / ou=my users,dc=mydomain,dc=com
whole domain if omitted

seachScope can be:
Base,OneLevel,Subtree
Subtree if omitted

maxWarn and maxCrit but me integer

Usage samples

Directly from PowerShell:

PS C:Program FilesNSClient++scripts> . .lotp_check_ad_accounts.ps1 AccountInactive "dc=mydomain,dc=com" subtree 5 10
CRITICAL: 216 AccountInactive|216;5;10
PS C:Program FilesNSClient++scripts>

Through NRPE:

[root~]# /usr/lib64/nagios/plugins/check_nrpe -H prd-dom-dc01 -n -c check_ad_account -a AccountInactive "dc=pmside,dc=net" subtree 5 10

CRITICAL: 216 AccountInactive|'AccountInactive'=216;5;10

[root~]#

Install:

On DC:

  • Enable powershell script execution without signed : Set-ExecutionPolicy RemoteSigned
  • copy script in folder C:Program FilesNSClient++scripts
  • Add to nsclient.ini:
    • [/settings/external scripts/wrapped scripts]
      check_ad_account=lotp_check_ad_accounts.ps1 $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$

Setup:

For example on Centreon, adding this command:

$USER1$/check_nrpe -H $HOSTADDRESS$ -n -c check_ad_account -a $ARG1$ "$ARG2$" $ARG3$ $ARG4$ $ARG5$

Download

(remove .txt at the end)

lotp_check_ad_accounts.ps1

Directly in case download fail:

# ====================================================================
# Search in AD for lockedout account. To be used through NRPE / nsclient++
# Author: Mathieu Chateau - LOTP
# mail: mathieu.chateau@lotp.fr
# version 0.1
# ====================================================================#
# Require Set-ExecutionPolicy RemoteSigned.. or sign this script with your PKI 
#
# ============================================================
#
#  Do not change anything behind that line!
#
param 
(
    [string]$action="LockedOut",
    [string]$searchBase="",
    [string]$searchScope="Subtree",
    [int]$maxWarn=5,
    [int]$maxCrit=10
)

# check that powershell ActiveDirectory module is present

if(Get-Module -Name "ActiveDirectory" -ListAvailable)
{
    try
    {
        Import-Module -Name ActiveDirectory
    }
    catch
    {
        Write-Host "CRITICAL: Missing PowerShell ActiveDirectory module"
        exit 2
    }
}
else
{
    Write-Host "CRITICAL: Missing PowerShell ActiveDirectory module"
    exit 2
}

# check params if provided

if($action -notmatch "^(AccountDisabled|AccountExpired|AccountExpiring|AccountInactive|LockedOut|PasswordExpired|PasswordNeverExpires)$")
{
    Write-Host "CRITICAL: action parameter can only be AccountDisabled,AccountExpired,AccountExpiring,AccountInactive,LockedOut,PasswordExpired,PasswordNeverExpires. Provided $action"
    exit 2
}
if($searchScope -notmatch "^(Base|OneLevel|Subtree)$")
{
    Write-Host"CRITICAL: searchScope parameter can only be Base,OneLevel,Subtree. Provided $searchScope"
    exit 2
}
if(($searchBase -ne "") -and $searchBase -ne ((Get-ADDomain).DistinguishedName))
{
    $search=Get-ADObject -Filter 'ObjectClass -eq "OrganizationalUnit" -and DistinguishedName -eq $searchBase'

if ($search.Count -ne 1)
    {
        Write-Host"CRITICAL: SearchBase not found or duplicate. Provided $searchBase"
        exit 2
    }
}
else
{
    $searchBase=(Get-ADDomain).DistinguishedName
}

$command="Search-ADAccount -"+$action+" -SearchBase '"+$searchBase+"' -SearchScope "+$searchScope

$result=invoke-expression $command

if($result.Count -gt $maxCrit)
{
    $state="CRITICAL"
    $exitcode=2
}
elseif($result.Count -gt $maxWarn)
{
    $state="WARNING"
    $exitcode=1
}
else
{
    $state="OK"
    $exitcode=0
}

$output=$state+": "+$result.Count+""+$action+"|"+$action+"="+$result.Count+";"+$maxWarn+";"+$maxCrit

Write-Host $output
exit $exitcode

3 thoughts on “Nagios: monitor Active Directory accounts”

  1. Line 24 & 28 need a space between the cmdlet and the parameter.
    Get-Module -Name
    Import-Module -Name

Leave a Comment