Nagios: Superviser la santé Hyper-V 2012 – BPA & VM

Ce plugin Nagios vérifie la santé d’un serveur Hyper-V via un script PowerShell + NRPE (nsclient++):

  • Exécute et récupère le résultat du scan BPA (Best Practice Analyzer)
  • Vérifie que toutes les VM sont en cours d’exécution
  • Vérifie qu’aucune VM n’a un état de fonctionnement autre que normal

Les états avertissements et critiques sont déclenchés par la somme des:

  • Quantité d’alertes BPA
  • Nombre de VM dans un état autre que sain

Certaines VM (modèles…) peuvent être ignorées via un argument

Un nouveau scan BPA est lancé à chaque exécution, mais le résultat n’est récupéré que la fois suivante (async) (prend trop de temps).

Les données de performances suivantes sont fournies:

  • # VM arrêtées,
  • # VM avec problème de santé,
  • # Erreurs BPA
  • # Avertissements BPA

Configuration testée

Linux:

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

Windows:

  • Windows Server 2012 (nécessaire pour avoir le module PowerShell Hyper-V)
  • nsclient++ 0.4.1 x64

Arguments du script

  • excludeVM (séparées par des virgules)
  • maxWarn (Avertissement si supérieur) (1 par défaut)
  • maxError (Critique si supérieur) (5 par défaut)

maxWarn et maxCrit doivent être des entiers

Exemples d’utilisation

Exemple en exécution directe PowerShell:

PS C:Program FilesNSClient++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 FilesNSClient++scripts>

Exécution 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~]#

Installation:

Sur les Windows:

  • Activer l’exécution de scripts PowerShell non signés : Set-ExecutionPolicy RemoteSigned
  • copier le script dans C:Program FilesNSClient++scripts
  • Ajouter dans le fichier nsclient.ini:
    • [/settings/external scripts/wrapped scripts]
      check_hyper-v=lotp_check_hyper-v.ps1 -excludeVM $ARG1$ -maxWarn $ARG2$ -maxError $ARG3$

Configuration:

Par exemple, sur Centreon, en ajoutant la commande:

$USER1$/check_nrpe -H $HOSTADDRESS$ -n -t 60 -c check_hyper-v -a $ARG1$ $ARG2$ $ARG3$

Téléchargement

lotp_check_hyper-v.ps1

Code source en direct:

 

# ====================================================================
# 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

En préparant un plugin nagios sur la santé AD, dcdiag /e /c a eu la bonne idée de remonter cette alerte:

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

 

L’article Q312862 n’est plus vraiment d’actualité, mais le problème sous-jacent est bien réel.

Depuis Windows 2008, la réplication AD est censée se faire via DFS-R et non plus FRS. Cependant, cela implique de n’avoir plus que des DC > Windows Server 2003.

Donc si vos DC sont à jours, il faut utiliser dfsrmig dont les principales commandes sont:

Vérifier l’état global:

PS C:usersmchateauDesktop> dfsrmig /GetGlobalState

Current DFSR global state: 'Start'

Succeeded.

Les différents états possibles sont:

0 'Start'
1 'Prepared'
2 'Redirected'
3 'Eliminated'

==>Si vous êtes déjà en DFS-R, l’état est Eliminated.

 

Vérifier l’état de la migration:

PS C:usersmchateauDesktop> dfsrmig /GetMigrationState

All domain controllers have migrated successfully to the Global state ('Start').
Migration has reached a consistent state on all domain controllers.
Succeeded.

 

Passer à l’état Prepared:

PS C:usersmchateauDesktop> 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.

 

Vérifier l’état (en cours):

PS C:usersmchateauDesktop> 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:usersmchateauDesktop>

 

Il ne reste plus qu’à faire les 2 états suivants tour à tour:

dfsrmig /SetGlobalState 2
dfsrmig /SetGlobalState 3

 

Au final:

PS C:usersmchateauDesktop> 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 via nrpe

L’objectif de ce plugin est tester via ping plusieurs cibles depuis un serveur via nrpe. Ce n’est donc pas le serveur nagios, mais bien un serveur supervisé par celui-ci qui fait le test.

Le plugin est exécuté localement, appelé via NRPE (et donc nsclient++ par exemple).

Etant multi threadé, la vitesse d’exécution est presque constante (1.75s par cible en moyenne).

Configuration testée

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
  • Serveurs Core et normaux

Arguments du script

  • targets (séparées par des virgules, obligatoire)
  • maxWarn (Avertissement si le nombre de cible offline est supérieur) (1 par défaut)
  • maxError (Critique si le nombre de cible offline est supérieur) (5 par défaut)

maxWarn et maxCrit doivent être des entiers

Exemples d’utilisation

Exemple en exécution directe PowerShell:

PS C:Program FilesNSClient++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 FilesNSClient++scripts>

Exécution 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~]#

Installation:

Sur les Windows:

  • Activer l’exécution de scripts PowerShell non signés : Set-ExecutionPolicy RemoteSigned
  • copier le script dans C:Program FilesNSClient++scripts
  • Ajouter dans le fichier nsclient.ini:
    • [/settings/external scripts/wrapped scripts]
      check_multiping=lotp_check_multiping.ps1 -targets $ARG1$ -maxWarn $ARG2$ -maxError $ARG3$

Configuration:

Par exemple, sur Centreon, en ajoutant la commande:

$USER1$/check_nrpe -H $HOSTADDRESS$ -n -t 60 -c check_multiping -a $ARG1$ $ARG2$ $ARG3$

Téléchargement

lotp_check_multiping.ps1

(enlever le .txt à la fin)

code source en direct:

# ====================================================================
# 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

Top des possibilités:

  • le prompt Powershell n’est pas lancé en mode administrateur (prompt UAC)
  • Vous n’êtes pas administrateur local
  • Vous n’avez pas accès aux bases SQL. Le snapin doit se connecter à la base de configuration de la ferme.

Histoire de ne pas faire le post le plus court de l’année, vous pouvez vérifier avec Process Explorer si vous êtes vraiment administrateur (aka UAC elevated):

  • Deny : vous êtes membres mais UAC vous bloque. Il faut relancer en run as administrator
  • Owner: vous êtes bien administrateur avec UAC elevated. Donc c’est SQL le problème 😉

06-05-2013 22-52-21

06-05-2013 22-53-32

 

Nagios: Superviser les horloges Windows

L’objectif de ce plugin pour Nagios est de superviser l’heure sur les serveurs Windows non DC.

Les serveurs membres ne peuvent pas par défaut être interrogé en ntp comme les DC pour vérifier leur horloge.

J’utilise l’agent nsclient++ sur les serveurs afin de pouvoir exécuter des scripts PowerShell entre autre. On a donc:

Nagios => check_nrpe => script powershell => retour nagios

Cela fonctionne également sur les serveurs Core.

Si aucun serveur de référence n’est fourni, le script fonctionne ainsi:

  • Si un serveur de référence est fourni, utilisation de celui-ci
  • Sinon:
    • Si joint à un domaine, essaye de récupérer la variable logonserver. Si cela échoue, prend un DC au hasard. en cas d’erreur, essaye avec pool.ntp.org
    • Si n’est pas joint à un domaine, essaye avec pool.ntp.org

Fourni la « jigue » en temps que performance pour les graphes.

Configuration testée

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
  • Serveurs Core et normaux

Arguments du script

  • refTimeServer (AD find ou pool.ntp.org par défaut)
  • maxWarn (Avertissement si supérieur, en secondes) (1 par défaut)
  • maxError (Critique si supérieur, en secondes) (5 par défaut)

 

maxWarn et maxCrit doivent être des entiers

Exemples d’utilisation

Exemple en exécution directe 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>

Exécution 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~]#

Installation:

Sur les Windows:

  • Activer l’exécution de scripts PowerShell non signés : Set-ExecutionPolicy RemoteSigned
  • copier le script dans C:Program FilesNSClient++scripts
  • Ajouter dans le fichier nsclient.ini:
    • [/settings/external scripts/wrapped scripts]
      check_time=lotp_check_time.ps1 -refTimeServer $ARG1$ -maxWarn $ARG2$ -maxError $ARG3$

Configuration:

Par exemple, sur Centreon, en ajoutant la commande:

$USER1$/check_nrpe -H $HOSTADDRESS$ -n -c check_time -a "$ARG1$" $ARG2$ $ARG3$

Téléchargement

(enlever le .txt à la fin)

lotp_check_time.ps1

 

# ====================================================================
# 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 0x2

 

 

 

 

SharePoint n’est pas avare en message, et ils ont presque toujours une origine, reste à trouver laquelle…

Cette fois, le message suivant est apparu sur la ferme 2010 et 2013:
sharepoint event 8311

Ce qui donne:

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:nnSubject Name: CN=Server.mydomain.netnIssuer Name: CN=my-CA, DC=mydomain, DC=net

Errors:nn SSL policy errors have been encountered. Error code '0x2'..

 

Cause

Un certificat a été assigné dans IIS pour le site SharePoint Web Services (binding SSL port 32844).

 

Résolution

Le problème ne vient pas de la confiance du certificat, mais du subject name. Il s’avère que le serveur est enregistré avec le nom court dans la ferme, et que le certificat contient le FQDN.

2 solutions:

  • Générer un autre certificat avec un subject name qui correspond au serveur,
  • Renommer le serveur dans la ferme SharePoint.

C’est cette deuxième option qui a été renommé, à faire en PowerShell.

Lister les serveurs avec leur nom inscrit dans la ferme:

get-spserver

Renommer un serveur (à lancer localement sur le serveur):

Rename-SPServer -Identity MyServer -Name MyServer.MyDomain.net

Faire un iisreset ensuite, et patienter 10mn que la topology se mette à jour 🙂

 

Nagios: Superviser les certificats dans Windows

L’objectif de ce plugin pour Nagios est de superviser l’état des certificats, et leur date d’expiration en particulier (oui, je ne fais pas que du SCOM malgré un ouvrage ENI dessus!)

J’utilise l’agent nsclient++ sur les serveurs afin de pouvoir exécuter des scripts PowerShell entre autre. On a donc:

Nagios => check_nrpe => script powershell => retour nagios

Cela fonctionne également sur les serveurs Core.

Windows contient des certificats déjà expiré depuis longtemps. Le script contient une blacklist afin de les ignorer.

Configuration testée

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
  • Serveurs Core et normaux

Arguments du script

  • checkMyStore (oui par défaut)
  • checkRootStore (oui par défaut)
  • checkCAStore (oui par défaut)
  • checkAuthRootStore (oui par défaut)
  • checkSharePointStore (oui par défaut)
  • expireInDays (60 jours par défaut)
  • maxWarn (avertissement si supérieur)
  • maxCrit (Critique si supérieur)

Pour chaque store, la réponse doit être un booléen ($true /$false ou 1/0)

expireInDays,maxWarn et maxCrit doivent être des entiers

Exemples d’utilisation

Exemple en exécution directe PowerShell:

PS C:Program FilesNSClient++scripts> . .lotp_check_certificates.ps1
CRITICAL: www.lotp.fr:2013/06/30
PS C:Program FilesNSClient++scripts>

Exécution 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~]#

Installation:

Sur les Windows:

  • Activer l’exécution de scripts PowerShell non signés : Set-ExecutionPolicy RemoteSigned
  • copier le script dans C:Program FilesNSClient++scripts
  • Ajouter dans le fichier nsclient.ini:
    • [/settings/external scripts/wrapped scripts]
      check_certificate=lotp_check_certificate.ps1 $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$ $ARG6$ $ARG7$ $ARG8$

Configuration:

Par exemple, sur Centreon, en ajoutant la commande:

$USER1$/check_nrpe -H $HOSTADDRESS$ -n -c check_certificate -a $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$ $ARG6$ $ARG7$ $ARG8$

Téléchargement

(enlever le .txt à la fin)

lotp_check_certificates.ps1

Code source en direct si le téléchargement ne passe pas:

 

# ====================================================================
# 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