Nagios: monitor Hyper-V 2012 health – BPA & VM
0This Nagios plugin check Hyper-V 2012 server health through PowerShell + NRPE (nsclient++):
- Execute and retrieve BPA scan result (Best Practice Analyzer)
- Check that all VM are running
- Check that no VM are in any state other than “Operating normally”
Warning and Critical state are triggered by the sum of:
- BPA alerts
- # VM in unhealthy state
VM (models…) can be excluded through an argument
A new BPA scan is triggered at every execution, but new result is retrieved next time (async) (take too much time).
Provided performance data:
- # VM stopped,
- # VM unhealthy,
- # BPA errors
- # BPA warning
Tested setup
Linux:
- Centos 6.4 x64
- Nagios 3.4.4
- check_nrpe 2.13
- Centreon 2.4.2
Windows:
- Windows Server 2012 (needed to have PowerShell Hyper-V module)
- nsclient++ 0.4.1 x64
Script argument
- excludeVM (comma separated)
- maxWarn (Warning if aboce) (1 by default)
- maxError (Criticial if above) (5 by default)
maxWarn and maxCrit must be integer
Usages samples
Directly in PowerShell:
PS C:\Program Files\NSClient++\scripts>. .\lotp_check_hyper-v.ps1 WARNING: 'VM Not Running:'2 'VM issues:'0 BPA Error:1 BPA Warning:12|VM_Not_Running=2 VM_issues=0 BPA_Error=1 BPA_Warning=12 PS C:\Program Files\NSClient++\scripts>
Through NRPE:
[root~]# /usr/lib64/nagios/plugins/check_nrpe -H myMonitoredServer -n -c check_hyper-v WARNING: 'VM Not Running:'2 'VM issues:'0 BPA Error:1 BPA Warning:12|VM_Not_Running=2 VM_issues=0 BPA_Error=1 BPA_Warning=12 [root~]#
Install:
On Windows:
- Enable powershell script execution without signed : Set-ExecutionPolicy RemoteSigned
- copy script in folder C:\Program Files\NSClient++\scripts
- Add to nsclient.ini:
- [/settings/external scripts/wrapped scripts]
- check_hyper-v=lotp_check_hyper-v.ps1 -excludeVM $ARG1$ -maxWarn $ARG2$ -maxError $ARG3$
Setup:
On Centreon, by adding this command:
$USER1$/check_nrpe -H $HOSTADDRESS$ -n -t 60 -c check_hyper-v -a $ARG1$ $ARG2$ $ARG3$
Download
Source code:
# ==================================================================== # Ping a list of targets through NRPE # 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]$targets, [int]$maxWarn = 1, [int]$maxError = 5 ) $output="" $exitcode=2 $countOK=0 $countKO=0 $targetsArray=@() $targetsArray=$targets -split(' ') Remove-Job -Name * -Confirm:$false -Force foreach($t in $targetsArray) { Start-Job -Name $t -ArgumentList $t -ScriptBlock {param($t);if(Test-Connection -ComputerName $t -Count 2 -Quiet -ErrorAction SilentlyContinue){return $true}else{return $false}} |Out-Null } while(Get-Job -State Running) { Start-Sleep -Milliseconds 500 } foreach ($job in Get-Job) { $temp=Receive-Job -Name $job.Name if($temp) { $countOK++ } else { $countKO++ $output+=$job.Name+" - " } } if ($countKO -gt $maxError) { $state="CRITICAL" $exitcode=2 } elseif ($countKO -gt $maxWarn) { $state="WARNING" $exitcode=1 } else { $state="OK" $exitcode=0 } $output=$state+":"+$countOK+" online"+" - "+$countKO+" offline - "+$output $output+='|' $output+="online="+$countOK+";"+$maxWarn+";"+$maxError+";"+" " $output+="offline="+$countKO+";"+$maxWarn+";"+$maxError+";" Write-Host $output exit $exitcode |
dcdiag – VerifyEnterpriseReferences – msDFSR-ComputerReferenceBL – Q312862
0While writing a Nagios plugin on Active Directory health, dcdiag /e /c got the good idea to give this alert:
Starting test: VerifyEnterpriseReferences The following problems were found while verifying various important DN references. Note, that these problems can be reported because of latency in replication. So follow up to resolve the following problems, only if the same problem is reported on all DCs for a given domain or if the problem persists after replication has had reasonable time to replicate changes. [1] Problem: Missing Expected Value Base Object: CN=myDC,OU=Domain Controllers,DC=mydomain,DC=net Base Object Description: "DC Account Object" Value Object Attribute Name: msDFSR-ComputerReferenceBL Value Object Description: "SYSVOL FRS Member Object" Recommended Action: See Knowledge Base Article: Q312862
Article Q312862 is not really helpful, but the underlying problem is true.
Since Windows 2008, AD replication is meant through DFS-R and not FRS anymore. But it implies to have only DC > Windows Server 2003.
So if your DC are updated enough, you can use dfsrmig to migrate, which main commands are:
Check global state:
PS C:\users\mchateau\Desktop> dfsrmig /GetGlobalState Current DFSR global state: 'Start' Succeeded.
Values can be:
0 'Start' 1 'Prepared' 2 'Redirected' 3 'Eliminated'
==>if you are already in DFS-R, state is Eliminated.
Check migration state:
PS C:\users\mchateau\Desktop> dfsrmig /GetMigrationState
All domain controllers have migrated successfully to the Global state ('Start').
Migration has reached a consistent state on all domain controllers.
Succeeded.
Go from start to Prepared:
PS C:\users\mchateau\Desktop> dfsrmig /SetGlobalState 1 Current DFSR global state: 'Start' New DFSR global state: 'Prepared' Migration will proceed to 'Prepared' state. DFSR service will copy the contents of SYSVOL to SYSVOL_DFSR folder. If any domain controller is unable to start migration, try manual polling. Or run with option /CreateGlobalObjects. Migration can start anytime between 15 minutes to 1 hour. Succeeded.
Check state (in progress):
PS C:\users\mchateau\Desktop> dfsrmig /GetMigrationState
The following domain controllers have not reached Global state ('Prepared'):
Domain Controller (Local Migration State) - DC Type
===================================================
myDC01 ('Start') - Writable DC
myDC02 ('Start') - Writable DC
myDC03 ('Start') - Primary DC
myDC04 ('Start') - Writable DC
Migration has not yet reached a consistent state on all domain controllers.
State information might be stale due to Active Directory Domain Services latency.
PS C:\users\mchateau\Desktop>
You just have to go through the last two steps, turn by turn:
dfsrmig /SetGlobalState 2 dfsrmig /SetGlobalState 3
In the end:
PS C:\users\mchateau\Desktop> dfsrmig /GetMigrationState
All domain controllers have migrated successfully to the Global state ('Eliminated').
Migration has reached a consistent state on all domain controllers.
Succeeded.
Nagios: multithreaded multi ping through nrpe
0Multithreaded multiple ping targets from a remote server through nrpe / nsclient.
For example, if you have a remote site with one server, you can then use it to ping different targets (local switch, google…).
Return number of online/offline targets.
the multithreaded allow a quick execution even with high number of targets, even if they are offline.
typical execution time: 1.75 seconds per target, in average
Provide performance data to get the ratio offline/online.
Can specify number of target that must be offline before triggering warning and critical state.
Tested setup
Linux:
- Centos 6.4 x64
- Nagios 3.4.4
- check_nrpe 2.13
- Centreon 2.4.2
Windows:
- Windows Server 2008 R2 / 2012
- nsclient++ 0.4.1 x64 et x86
- Servers Core & GUI
Script arguments
- targets (separated by commas, MANDATORY)
- maxWarn (Warning if offline number above) (1 par défaut)
- maxError (Critical if offline number above) (5 par défaut)
maxWarn et maxCrit must be integer
Sample usages
Directly in PowerShell:
PS C:\Program Files\NSClient++\scripts>. .\lotp_check_multiping.ps1 www.google.com,www.lotp.fr 1 2 OK:2 online - 0 offline - |online=2;1;2; offline=0;1;2; PS C:\Program Files\NSClient++\scripts>
Through NRPE:
[root~]# /usr/lib64/nagios/plugins/check_nrpe -H myMonitoredServer -n -c check_multiping -a www.google.com,www.lotp.fr 1 2 OK:2 online - 0 offline - |'online'=2;1;2 'offline'=0;1;2 [root~]#
Install:
On Windows:
- Enable powershell script execution without signed : Set-ExecutionPolicy RemoteSigned
- copy script in folder C:\Program Files\NSClient++\scripts
- Add to nsclient.ini:
- [/settings/external scripts/wrapped scripts]
- check_multiping=lotp_check_multiping.ps1 -targets $ARG1$ -maxWarn $ARG2$ -maxError $ARG3$
Setup:
On Centreon, by adding this command:
$USER1$/check_nrpe -H $HOSTADDRESS$ -n -t 60 -c check_multiping -a $ARG1$ $ARG2$ $ARG3$
Download
(remove .txt at the end)
Source code :
# ==================================================================== # Ping a list of targets through NRPE # 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]$targets, [int]$maxWarn = 1, [int]$maxError = 5 ) $output="" $exitcode=2 $countOK=0 $countKO=0 $targetsArray=@() $targetsArray=$targets -split(' ') Remove-Job -Name * -Confirm:$false -Force foreach($t in $targetsArray) { Start-Job -Name $t -ArgumentList $t -ScriptBlock {param($t);if(Test-Connection -ComputerName $t -Count 2 -Quiet -ErrorAction SilentlyContinue){return $true}else{return $false}} |Out-Null } while(Get-Job -State Running) { Start-Sleep -Milliseconds 500 } foreach ($job in Get-Job) { $temp=Receive-Job -Name $job.Name if($temp) { $countOK++ } else { $countKO++ $output+=$job.Name+" - " } } if ($countKO -gt $maxError) { $state="CRITICAL" $exitcode=2 } elseif ($countKO -gt $maxWarn) { $state="WARNING" $exitcode=1 } else { $state="OK" $exitcode=0 } $output=$state+":"+$countOK+" online"+" - "+$countKO+" offline - "+$output $output+='|' $output+="online="+$countOK+";"+$maxWarn+";"+$maxError+";"+" " $output+="offline="+$countKO+";"+$maxWarn+";"+$maxError+";" Write-Host $output exit $exitcode |
SharePoint: The local farm is not accessible. Cmdlets with FeatureDependencyId are not registered
0Top issues:
- Powershell prompt not started with run as administrator (UAC)
- You are not a local admin at all,
- You don’t have access to database in SQL. Snapin must connect to SQL database.
For the UAC stuff, you can use Process Explorer to be sure you are really an admin (UAC elevated):
- Deny : You are memver but UAC is blocking you (filtered). Restart with run as administrator
- Owner: You are really admin with UAC elevated. Check SQL rights
Nagios: Monitor local Windows time
0Check local time against a provided source or AD(autodetect) or pool.ntp.org through NRPE / nsclient++.
Windows Server that are not DC can’t be tested through NTP by default.
This script is executed locally and compare time with w32tm tool.
Workflow:
- If reference server is provided, it’s used directly.
- If no reference server is provided:
- if domain joined:
- Try to use logonserver variable, to get closest live DC.
- Else auto find a DC (random) which is not itself and compare time.
- Else, use pool.ntp.org
- If workgroup:use pool.ntp.org
Provide performance data (offset jig) to get graphs
tested setup
Linux:
- Centos 6.4 x64
- Nagios 3.4.4
- check_nrpe 2.13
- Centreon 2.4.2
Windows:
- Windows Server 2003 / 2008 R2 / 2012
- nsclient++ 0.4.1 x64 et x86
- Servers Core & GUI
Script arguments:
- refTimeServer (AD autofind or pool.ntp.org by default)
- maxWarn (Warning if above, in second) (1 by default)
- maxError (Critical if above, in second) (5 by default)
maxWarn and maxCrit but me integer.
The time is compared in absolute, so it works either the shift is positive or negative
Sample usages
Directly in PowerShell:
PS C:Program FilesNSClient++scripts> . .\lotp_check_time.ps1 OK:-00.0307684s - checked against pool.ntp.org|offset=-00.0307684s;1;5; PS C:Program FilesNSClient++scripts>
Through NRPE:
[root~]# /usr/lib64/nagios/plugins/check_nrpe -H myserver -n -c check_time -a "myPDCServer" 1 5 OK:+00.0671837s - checked against myPDCServer|'offset'=0.06718s;1;5 [root~]#
Install:
On Windows:
- Enable powershell script execution without signed : Set-ExecutionPolicy RemoteSigned
- copy script in folder C:\Program Files\NSClient++\scripts
- Add to nsclient.ini:
- [/settings/external scripts/wrapped scripts]
- check_time=lotp_check_time.ps1 -refTimeServer $ARG1$ -maxWarn $ARG2$ -maxError $ARG3$
Setup:
On Centreon, by adding this command:
$USER1$/check_nrpe -H $HOSTADDRESS$ -n -c check_time -a \"$ARG1$\" $ARG2$ $ARG3$
Download
(remove .txt at the end)
# ==================================================================== # Check time against DC or specified server through NRPE / w32tm # 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]$refTimeServer, [int]$maxWarn = 1, [int]$maxError = 5 ) $output="" $exitcode=2 $random= if(($refTimeServer -eq $null) -or ($refTimeServer -eq "") -or ($refTimeServer -eq " ")) { $refTimeServer=$env:LOGONSERVER -replace ('\\',"") if(($refTimeServer -match "^$|^ $") -or ($env:LOGONSERVER -match $refTimeServer)) { if((gwmi win32_computersystem).partofdomain -eq $true) { #Must use select and not .Name directly. If some DC are down, command will be empty with .Name $fromAD=(([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain() | % { $_.DomainControllers }))| select Name foreach ($entry in $fromAD) { if(($env:COMPUTERNAME -match $entry) -or ($entry -match $env:COMPUTERNAME)) { #this server is a DC, can't check time against itself $fromAD.Remove($entry) } } if($fromAD.Count -gt 1) { #get a random DC from AD, as no server provided and no logon server could be found $refTimeServer=(Get-Random -InputObject $fromAD).Name } else { #only one DC, defaulting to internet $refTimeServer="pool.ntp.org" } } else { #Workgroup but no server to check time against provided. Defaulting to internet to do something $refTimeServer="pool.ntp.org" } } } if(($refTimeServer -eq $null) -or ($refTimeServer -eq "") -or ($refTimeServer -eq " ")) { #Something bad happened. Should never happen Write-Host "CRITICAL: can't auto detect logon server to check against. Need to specify manually using refTimeServer argument" exit 2 } $temp=w32tm /stripchart /computer:$refTimeServer /period:1 /dataonly /samples:1 $temp=($temp | select -Last 1) -replace (".*, ","") $temp=$temp -replace ("s$","") if ($temp -match "^(\+|\-)[0-9]+\.[0-9]+$") { $output=$temp+"s - checked against "+$refTimeServer if ([math]::abs($temp) -gt $maxError) { $state="CRITICAL" $exitcode=2 } elseif ([math]::abs($temp) -gt $maxWarn) { $state="WARNING" $exitcode=1 } else { $state="OK" $exitcode=0 } } else { $output="Error: - used $refTimeServer as time server - output:$temp" $exitcode=2 } $output=$state+":"+$output+$random+'|'+"offset="+$temp+"s"+";"+$maxWarn+";"+$maxError+";" Write-Host $output exit $exitcode |
SharePoint – event 8311 – SSL policy errors have been encountered. Error code 0×2
0
SharePoint is generous in error messages, and they nearly get a reason evertytime…Just need to figure out
This time, the following error message appeared both on 2010 and 2013 farm:

Which give in text:
Log Name: Application Source: Microsoft-SharePoint Products-SharePoint Foundation Event ID: 8311 Task Category: Topology Level: Error Description: An operation failed because the following certificate has validation errors:\n\nSubject Name: CN=Server.mydomain.net\nIssuer Name: CN=my-CA, DC=mydomain, DC=net Errors:\n\n SSL policy errors have been encountered. Error code '0x2'..
Cause
A certificate has been binded to IIS for SharePoint Web Services site ((binding SSL port 32844).
Resolution
The server is registered in SharePoint with its short name and this certificate subject contains the FQDN name.
2 solutions:
- Get another certificate with a matching subject name,
- Rename server in SharePoint farm to its FQDN
That last solution was chosen, done in PowerShell.
Get servers with their registered name in farm:
get-spserver
Rename one server (must be done locally on the server):
Rename-SPServer -Identity MyServer -Name MyServer.MyDomain.net
Follow by a iisreset, and wait 10mn to get topology updated
Nagios: Monitor Windows certificates
0
Plugin’s job si to monitor certificates in Windows store expiration date.
I am using nsclient++ on servers to execute PowerShell scripts & co. The flow is:
Nagios => check_nrpe => powershell script => nagios feedback
This works also on Server Core.
Windows contains many already expired certificate. This script contains a blacklist to ignore them.
tested setup
Linux:
- Centos 6.4 x64
- Nagios 3.4.4
- check_nrpe 2.13
- Centreon 2.4.2
Windows:
- Windows Server 2003 / 2008 R2 / 2012
- nsclient++ 0.4.1 x64 et x86
- Servers Core & GUI
Script arguments
- checkMyStore (on by default)
- checkRootStore (on by default)
- checkCAStore (on by default)
- checkAuthRootStore (on by default)
- checkSharePointStore (on by default)
- expireInDays (60 days by default)
- maxWarn (warning if above)
- maxCrit (Critical if above)
For each store, argument must be a boolean ($true /$false ou 1/0)
expireInDays,maxWarn and maxCrit must be integers
Sample usages
Directly in PowerShell:
PS C:\Program Files\NSClient++\scripts> . .\lotp_check_certificates.ps1 CRITICAL: www.lotp.fr:2013/06/30 PS C:\Program Files\NSClient++\scripts>
Through NRPE:
[root~]# /usr/lib64/nagios/plugins/check_nrpe -H myserver -n -c check_certificate -a \$true \$true \$true \$true \$true 60 0 0 CRITICAL: www.lotp.fr:2013/06/30 [root~]#
Install:
On Windows:
- Enable powershell script execution without signed : Set-ExecutionPolicy RemoteSigned
- copy script in folder C:\Program Files\NSClient++\scripts
- Add to nsclient.ini:
- [/settings/external scripts/wrapped scripts]
check_certificate=lotp_check_certificate.ps1 $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$ $ARG6$ $ARG7$ $ARG8$
- [/settings/external scripts/wrapped scripts]
Setup:
On Centreon, by adding this command:
$USER1$/check_nrpe -H $HOSTADDRESS$ -n -c check_certificate -a $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$ $ARG6$ $ARG7$ $ARG8$
Download
(remove .txt at the end)
Code source here:
# ==================================================================== # Check certificates health state # 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 ( [bool]$checkMyStore=$true, [bool]$checkRootStore=$true, [bool]$checkCAStore=$true, [bool]$checkAuthRootStore=$true, [bool]$checkSharePointStore=$true, [int]$expireInDays=60, [int]$maxWarn = 1, [int]$maxError = 0 ) # blacklist all third party known expired certificates in root & co, on Windows Server 2003, 2008 & 2012 $blacklist=@( "109F1CAED645BB78B3EA2B94C0697C740733031C", "12519AE9CD777A560184F1FBD54215222E95E71F", "127633A94F39CBF6EDF7C7BF64C4B535E9706E9A", "18F7C1FCC3090203FD5BAA2F861A754976C8DD25", "23EF3384E21F70F034C467D4CBA6EB61429F174E", "245C97DF7514E7CF2DF8BE72AE957B9E04741E85", "24A40A1F573643A67F0A4B0749F6A22BF28ABB6B", "24BA6D6C8A5B5837A48DB5FAE919EA675C94D217", "2B84BFBB34EE2EF949FE1CBE30AA026416EB2216", "3A850044D8A195CD401A680C012CB0A3B5F8DC08", "4463C531D7CCC1006794612BB656D3BF8257846F", "47AFB915CDA26D82467B97FA42914468726138DD", "4BA7B9DDD68788E12FF852E1A024204BF286A8F6", "4D8547B7F864132A7F62D9B75B068521F10B68E3", "4DF13947493CFF69CDE554881C5F114E97C3D03B", "4EF2E6670AC9B5091FE06BE0E5483EAAD6BA32D9", "4F65566336DB6598581D584A596C87934D5F2AB4", "51C3247D60F356C7CA3BAF4C3F429DAC93EE7B74", "53DECDF3BC1BDE7C9D1CEDAE718468CA20CC43E7", "587B59FB52D8A683CBE1CA00E6393D7BB923BC92", "5E997CA5945AAB75FFD14804A974BF2AE1DFE7E1", "637162CC59A3A1E25956FA5FA8F60D2E1C52EAC6", "6690C02B922CBD3FF0D0A5994DBD336592887E3F", "67EB337B684CEB0EC2B0760AB488278CDD9597DD", "687EC17E0602E3CD3F7DFBD7E28D57A0199A3F44", "688B6EB807E8EDA5C7B17C4393D0795F0FAE155F", "68ED18B309CD5291C0D3357C1D1141BF883866B1", "720FC15DDC27D456D098FABF3CDD78D31EF5A8DA", "7613BF0BA261006CAC3ED2DDBEF343425357F18B", "7A74410FB0CD5C972A364B71BF031D88A6510E9E", "7AC5FFF8DCBC5583176877073BF751735E9BD358", "7B02312BACC59EC388FEAE12FD277F6A9FB4FAC1", "7CA04FD8064C1CAA32A37AA94375038E8DF8DDC0", "7D7F4414CCEF168ADF6BF40753B5BECD78375931", "7F88CD7223F3C813818C994614A89C99FA3B5247", "838E30F77FDD14AA385ED145009C0E2236494FAA", "8977E8569D2A633AF01D0394851681CE122683A6", "8B24CD8D8B58C6DA72ACE097C7B1E3CEA4DC3DC6", "9078C5A28F9A4325C2A7C73813CDFE13C20F934E", "90DEDE9E4C4E9F6FD88617579DD391BC65A68964", "96974CD6B663A7184526B1D648AD815CF51E801A", "9845A431D51959CAF225322B4A4FE9F223CE6D15", "9BACF3B664EAC5A17BED08437C72E4ACDA12F7E7", "9FC796E8F8524F863AE1496D381242105F1B78F5", "A1505D9843C826DD67ED4EA5209804BDBB0DF502", "A399F76F0CBF4C9DA55E4AC24E8960984B2905B6", "A3E31E20B2E46A328520472D0CDE9523E7260C6D", "A5EC73D48C34FCBEF1005AEB85843524BBFAB727", "B19DD096DCD4E3E0FD676885505A672C438D4E9C", "B533345D06F64516403C00DA03187D3BFEF59156", "B6AF5BE5F878A00114C3D7FEF8C775C34CCD17B6", "B72FFF92D2CE43DE0A8D4C548C503726A81E2B93", "CFDEFE102FDA05BBE4C78D2E4423589005B2571D", "D29F6C98BEFC6D986521543EE8BE56CEBC288CF3", "DBAC3C7AA4254DA1AA5CAAD68468CB88EEDDEEA8", "E38A2B7663B86796436D8DF5898D9FAA6835B238", "EC0C3716EA9EDFADD35DFBD55608E60A05D3CBF3", "EF2DACCBEABB682D32CE4ABD6CB90025236C07BC", "F5A874F3987EB0A9961A564B669A9050F770308A", "F88015D3F98479E1DA553D24FD42BA3F43886AEF") $output="" $outputNames="" $countMyStore=0 $countRootStore=0 $countCAStore=0 $countAuthRootStore=0 $countSharePointStore=0 $countTotal=0 $allCerts=Get-ChildItem -Path cert: -Recurse | ? { ($_.Notafter -lt (get-date).AddDays($expireInDays)) -and ($_.PSPParentPath -notmatch "Disallowed") -and ($blacklist -notcontains $_.Thumbprint)} | select NotAfter,FriendlyName,PSParentPath function outputCert ($temp) { $outputTemp="" foreach ($t in $temp) { $outputTemp+=$t.FriendlyName+":"+(get-date -Date $t.NotAfter -format "yyyy/MM/dd")+" " } return $outputTemp } # check params if provided if($checkMyStore) { $temp=@($allCerts | ? {$_.PSParentPath -match "\\My$"}) $countMyStore=$temp.Count if($temp.Count -gt 0) { $outputNames+=outputCert $temp } } if($checkRootStore) { $temp=@($allCerts | ? {$_.PSParentPath -match "\\Root$"}) $countRootStore=$temp.Count if($temp.Count -gt 0) { $outputNames+=outputCert $temp } } if($checkCAStore) { $temp=@($allCerts | ? {$_.PSParentPath -match "\\CA$"}) $countCAStore=$temp.Count if($temp.Count -gt 0) { $outputNames+=outputCert $temp } } if($checkAuthRootStore) { $temp=@($allCerts | ? {$_.PSParentPath -match "\\AuthRoot$"}) $countAuthRootStore=$temp.Count if($temp.Count -gt 0) { $outputNames+=outputCert $temp } } if($checkSharePointStore) { $temp=@($allCerts | ? {$_.PSParentPath -match "\\SharePoint$"}) $countSharePointStore=$temp.Count if($temp.Count -gt 0) { $outputNames+=outputCert $temp } } foreach ($var in (Get-Variable -Name "count*Store")) { $countTotal+=$($var).Value } if($countTotal -gt $maxError) { $state="CRITICAL" $exitcode=2 } elseif($countTotal -gt $maxWarn) { $state="WARNING" $exitcode=1 } else { $state="OK" $exitcode=0 } $output=$state+": "+$outputNames Write-Host $output exit $exitcode |
Nagios: monitor Active Directory accounts
0Check 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 Files\NSClient++\scripts> . .\lotp_check_ad_accounts.ps1 AccountInactive "dc=mydomain,dc=com" subtree 5 10 CRITICAL: 216 AccountInactive|216;5;10 PS C:\Program Files\NSClient++\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 Files\NSClient++\scripts
- Add to nsclient.ini:
- [/settings/external scripts/wrapped scripts]
check_ad_account=lotp_check_ad_accounts.ps1 $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$
- [/settings/external scripts/wrapped scripts]
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)
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
IT++: Manage better or buy stronger ?
0
Computing, as with many things, ends up being cramped in the existing system. Maybe a little faster in computing than in other areas. Arises always a choice between better manage existing versus invest in a new solution / make an upgrade.
Better manage existing
This choice is more courageous than the second, but also more risky. It means that you think you can do better than what has been done since the beginning. This is generally characterized by time to spend with a gain difficult to estimate in advance. I think we should try it first because:
- It will potentially generate savings, even if it is insufficient and that we should still invest.
- It will better understand the need for reviewing the uses, and thus justify the investment potential.
- It shows that you not only “invest”.
The main thing is to set a goal in terms of time and load to produce a result. It should, however, never exceed a certain % that would cost the latter.
Demand in computing resource inexorably raise in business. The most strategic projects are generally subject to a “capacity planning” to ensure that the solution will last the famous 3 or 4 years of depreciation. There are some poor parents who rarely benefit from this treatment:
- Storage of office files,
- Mail Storage,
- Network usage (inter sites, and Internet).

Requesting household in the office files is like rowing in the desert. Everyone claims to have better things to do, but nobody wants to pay the price that it costs (central storage €MC / N€tApp, backup …). To stop this bleeding, miracle solutions have emerged (3 tiers archiving, deduplication, SharePoint …). This last allows indexing, which is almost worse. How to find where in a shambles without clean his room. Not only users do not want to delete old files, but they do not want to classify either…
Fortunately, we can transform the virus in a vaccine: searching words salaries and bonuses. Guaranteed Results!
The network is part of the heavy investment that work per stages. Storage and backup are also in. Solutions exist for quite some time, because it was the first point of contention:
- QOS: Manage the pipe: ensure flow, restricting others
- Compression: Riverbed & co. Hope that the data are redundant and do the equivalent of a “zip” on network streams.
In response to this, I propose two approaches in parallel:
- Ensure that best “minimum” practices are applied
- Equip IT to be able to do chargeback.
Some good proven practices:
- http / https flows are compressed by Web servers and proxy
- Replications (DFS, SQL …) between sites are made during peak hours or with integrated bandwidth management,
- Favor sending Delta rather than complete
- Search the largest files,
- Block from the start rather than a posteriori (media files …)
- Set quotas to manage unplanned growth. Even if blocking is not really possible.
- Note any “temporary” solution, identifying the applicant, the reason and the date of removal,
- Put safety (warning / blocking) below the actually blocking values .
- After putting into production, revalidate the initial capacity planning.
When needs are for a specific project, it is often easy to identify the pattern of costs. This is more difficult when it comes to the Internet or storage. Chargeback tools measure consumption. Even if the chargeback is not done, it clearly identifies the consumer, and ventilate the cost of the next upgrade.
Invest
This solution is certainly (or so) an immediate response to a problem or need. On some issues, such as office files, it cannot attract the wrath of users, especially when they do not hesitate to compare the price of a 1TB disk from the dealer on the corner. However there are cases where this choice does not bring the expected benefits. This is particularly the case with performance issues, where to buy a second server does not necessarily mean twice faster.
The investment is often favored because it also helps to have resources to carry out the actions. If you want to optimize your virtual infrastructure, you may be struggling to get a budget at most for an audit. So if you do a project with new servers and upgrade, you will be given the budget for it, with the needed resources. This is due to the difficulty of displaying earnings before optimization.
Conclusion
I recommend the following actions for the IT++ “label”:
- Have key indicators of saturation. These should be sufficient to have the time to conduct an optimization phase. Otherwise we find ourselves back to the wall and the investment will be systematically used.
- Request exercise to quantify the consumption of resources in projects. Use upgrade to request it on existing project. Check after the difference between the expected and the actual. The figures are as interesting as the awareness of people about the impact of their project.
- When a solution to a consumption problem is identified in a project (enable http compression), include it as the default for all new projects. Ask the existing one to check if it applies too.
- Implement chargeback tools on shared items and where the consumer is not clearly identifiable.
- Verify that consumption graphs are actually available on the key elements of architecture: storage, network, processor, memory. It is not when there is a saturation that these graphs must be implemented.
- Reduce the price of central storage GB. This allows easy recognition when applications. Ditto for the network.
- Challenging choices in the past renewals architecture. We made some choices based on:
- context
- The state of technology (maturity, cost, knowledge)
- budget.
Sometimes it is even others who have made these choices on the current architecture. It less engaging “just renew”, but it locks you indirectly limited choices for the future.

