Param ([switch]$help = $false,[switch]$enable_tracing = $false,[String]$AlertName,[String]$ResolutionStateName,[String]$Severity,[String]$ManagedEntityFullName,[String]$source, [String]$AlertDescription)
# v3.0 only, several features used will not work with 2.0
Set-StrictMode -Version 3.0
# Send XML payload to NRDP processor.
function send_alert_to_nagios([String]$xmlPost, [Hashtable]$aryNagVars) {
$webAgent = New-Object System.Net.WebClient
$nvcWebData = New-Object System.Collections.Specialized.NameValueCollection
$nvcWebData.Add('token', $aryNagVars['nrdptoken'])
$nvcWebData.Add('cmd', 'submitcheck')
$nvcWebData.Add('XMLDATA', $xmlPost)
if ($aryMainConf['main']['trace_mode_enabled'] -eq 1) {
logger( "Sending NRDP check: `n$xmlPost")
}
$strWebResponse = $webAgent.UploadValues($aryNagVars['nrdpurl'], 'POST', $nvcWebData)
$strReturn = [System.Text.Encoding]::ASCII.GetString($strWebResponse)
if ($aryMainConf['main']['trace_mode_enabled'] -eq 1) {
logger( "NRDP replied: `n$strReturn")
}
if ($strReturn.Contains("OK")) {
if ($aryMainConf['main']['trace_mode_enabled'] -eq 1) {
logger("SUCCESS - SCOM checks succesfully sent")
}
return $true
} else {
logger("ERROR - SCOM checks failed to send")
return $false
}
}
# Generate XML information for NRDP. Probably should change this to a bulk submission in the future instead of sending every alert individually.
function generate_alert_xml([Hashtable]$aryNagVars) {
$aryNagVars['output'] = [System.Web.HttpUtility]::HtmlEncode($aryNagVars['output'])
$xmlBuilder = "`n"
$xmlBuilder += "`n`t"
$xmlBuilder += "`n`t`t" + $aryNagVars['hostname'] + ""
$xmlBuilder += "`n`t`t" + $aryNagVars['service'] + ""
$xmlBuilder += "`n`t`t" + $aryNagVars['state'] + ""
$xmlBuilder += "`n`t`t"
$xmlBuilder += "`n`t"
$xmlBuilder += "`n"
return $xmlBuilder
}
# Log writing mechanism.
function logger([String]$strMessage) {
$dtTime = Get-Date
$strMessage = $dtTime.ToString() + " " + $strMessage
Write-Host $strMessage
if ($aryMainConf['logging']['log_enable'] -eq 1) {
$strLogFile = $aryMainConf['logging']['log_full_path']
$strMessage | Out-File $strLogFile -Encoding ascii -Append
}
}
# Import scombag main configuration file.
function import_main_config([String]$strExecutingPath) {
$strConfigFile = $strExecutingPath + "scomnagios.ini"
if (Test-Path $strConfigFile) {
# PS has no INI import function :( this is a simple INI import mechanism.
$aryIniContents = @{}
switch -regex -file $strConfigFile {
"^\[(.+)\]\s*$" {
$strHeading = $Matches[1]
$aryIniContents[$strHeading] = @{}
}
"^\s*(\S.*?)\s*=\s*(\S.*?)\s*$" {
$strKey = $Matches[1]
$strValue = $Matches[2]
$aryIniContents[$strHeading][$strKey] = $strValue
}
}
} else {
Write-Host "Unable to find main config file at path: $strConfigFile"
exit 2
}
return $aryIniContents
}
function help {
$strVersion = "v0.1"
$strNRDPVersion = "1.2"
Write-Host "SCOM-Nagios version: $strVersion for NRDP version: $strNRDPVersion"
Write-Host "GNU GPL License"
Write-Host "Usage: scomnagios.ps1 alertname resolutionstate severity managedentityname description `n"
Write-Host @'
-help
Display this help text.
-enable_tracing
Enable a verbose tracing execution. Used for testing changes to the map file.
'@
exit 0
}
##########################################
### BEGIN MAIN
##########################################
if ($help) {
help
}
Add-Type -Assembly System.Web
# Set the script home directory
if( $PSCommandPath ) {
$strExecutingPath = Split-Path -parent $PSCommandPath
Set-Location -Path $strExecutingPath
if (!("\" -eq $strExecutingPath.Substring($strExecutingPath.Length - 1, 1))) {
$strExecutingPath = $strExecutingPath + "\"
}
} else {
$strExecutingPath = "\"
}
#Import-Module OperationsManager -ErrorVariable strImportError
#if ($strImportError) {
# logger("Error loading one or more module(s): " + $strImportError)
# logger("Unable to continue.")
# exit 2
#}
# Import and validate the main configuration file
$aryMainConf = import_main_config($strExecutingPath)
Set-Variable -Name $aryMainConf -Scope Global
if ($enable_tracing) {
$aryMainConf['main']['trace_mode_enabled'] = 1
}
# Roll over logs and initialize logging.
if ($aryMainConf['logging']['log_enable'] -eq 1) {
if (!("\" -eq $aryMainConf['logging']['log_dir'].Substring($aryMainConf['logging']['log_dir'].Length - 1, 1))) {
$aryMainConf['logging']['log_dir'] = $aryMainConf['logging']['log_dir'] + "\"
}
if (Test-Path $aryMainConf['logging']['log_dir']) {
$aryMainConf['logging']['log_full_path'] = $aryMainConf['logging']['log_dir'] + $aryMainConf['logging']['log_name']
} elseif (Test-Path $strExecutingPath + $aryMainConf['logging']['log_dir']) {
$aryMainConf['logging']['log_full_path'] = $strExecutingPath + $aryMainConf['logging']['log_dir'] + $aryMainConf['logging']['log_name']
} else {
Write-Host "Can't find log directory. Unable to continue."
exit 2
}
$dtStartTime = Get-Date
$bLogExists = Test-Path $aryMainConf['logging']['log_full_path']
if ($aryMainConf['main']['trace_mode_enabled'] -eq 1) {
Add-Content $aryMainConf['logging']['log_full_path'] "`r`n############################################################"
}
Add-Content $aryMainConf['logging']['log_full_path'] "Nagios relay running at: $dtStartTime"
}
if ($aryMainConf['main']['trace_mode_enabled'] -eq 1) {
logger("Trace mode enabled. This is a tracing run.")
}
# process parameters
# activecheck hostname service state output
# nrdptoken nrdpurl
if ($aryMainConf['main']['trace_mode_enabled'] -eq 1) {
logger("ManagedEntityFullName = $ManagedEntityFullName")
logger("AlertName = $AlertName")
logger("ResolutionStateName = $ResolutionStateName")
logger("Severity = $Severity")
logger("Source = $Source")
}
$nagvars = @{}
$nagvars['nrdptoken'] = $aryMainConf['nrdp']['token']
$nagvars['nrdpurl'] = $aryMainConf['nrdp']['url']
$nagvars['activecheck'] = 0
# Remember these are string comparisons!
if ( $ResolutionStateName -eq "Closed" ) {
$nagvars['state'] = 0
} elseif ( $Severity -eq 2 ) {
$nagvars['state'] = 2
} else {
$nagvars['state'] = 1
}
if( ! $AlertDescription ) {
$AlertDescription = $Source
}
if( $AlertDescription ) {
if( $nagvars['state'] -gt 0 ) {
$nagvars['output'] = "["+$ResolutionStateName+"] "+$AlertName + '\n' + ( $AlertDescription -replace '<','<' -replace '>','>')
} else {
$nagvars['output'] = "["+$ResolutionStateName+"] "+$AlertName
}
} else {
$nagvars['output'] = "["+$ResolutionStateName+"] "+$AlertName + ": Status "+$nagvars['state']
}
if( $aryMainConf['main']['handle_links'] -eq 1 ) {
$nagvars['output'] = $nagvars['output'] -replace '((https?|ftp|mailto)://\S+)','<A HREF="${1}">${1}</A>'
}
if( $aryMainConf['main']['force_error_status'] -gt 0 -and $nagvars['state'] -gt 0 ) {
if ($aryMainConf['main']['trace_mode_enabled'] -eq 1) {
logger("Forcing status to "+$aryMainConf['main']['force_error_status'])
}
$nagvars['state'] = $aryMainConf['main']['force_error_status']
}
# This is something like objectname:fqdn[;netbios][;otherdata]
# note otherdata may contain a colon, objectname is [a-zA-z0-9\.]+
# Set to lower case and trim off domain though
if( $ManagedEntityFullName -ne "" ) {
$nagvars['hostname'] = $ManagedEntityFullName
$nagvars['hostname'] = $nagvars['hostname'] -replace '^.*?:'
$nagvars['hostname'] = $nagvars['hostname'] -replace ';.*$'
if( $aryMainConf['hostname']['lower_case'] ) {
$nagvars['hostname'] = $nagvars['hostname'].ToLower()
}
if( $aryMainConf['hostname']['domain'] ) {
$nagvars['hostname'] = $nagvars['hostname'] -replace ('.'+$aryMainConf['hostname']['domain']+'$')
}
} elseif( $aryMainConf['hostname']['domain'] -and ( $Source -match ("([a-zA-Z0-9\.\-]+)\."+$aryMainConf['hostname']['domain'])) ) {
$nagvars['hostname'] = $Matches[1]
if( $aryMainConf['hostname']['lower_case'] ) {
$nagvars['hostname'] = $nagvars['hostname'].ToLower()
}
} else {
$nagvars['hostname'] = "SCOM"
}
# Override Service settings based on $AlertName matches
$nagvars['service'] = "SCOM: Unknown"
if( $aryMainConf['service_desc']['default'] ) {
$nagvars['service'] = $aryMainConf['service_desc']['default']
}
if( $ManagedEntityFullName -match "^.*?;([-a-zA-Z0-9:]+)" ) {
$tag = $Matches[1]
if( $tag -and $nagvars['hostname'] -notmatch $tag.ToLower() ) {
$nagvars['service'] = "SCOM: "+$Matches[1]
if ($aryMainConf['main']['trace_mode_enabled'] -eq 1) {
logger("Overriding service default name with data from tag [$tag]")
}
}
}
if ($aryMainConf['service_desc']['max'] -gt 0) {
for($rule = 1;$rule -le $aryMainConf['service_desc']['max']; $rule++) {
if ($aryMainConf['service_desc']["desc$rule"]) {
if ($aryMainConf['main']['trace_mode_enabled'] -eq 1) {
logger("Processing match rule $rule")
}
if($aryMainConf['service_desc']["name$rule"] -and ( $AlertName -cmatch $aryMainConf['service_desc']["name$rule"] )) {
$nagvars['service'] = $aryMainConf['service_desc']["desc$rule"]
break
}
if($aryMainConf['service_desc']["entity$rule"] -and ( $ManagedEntityFullName -cmatch $aryMainConf['service_desc']["entity$rule"] )) {
$nagvars['service'] = $aryMainConf['service_desc']["desc$rule"]
break
}
if($aryMainConf['service_desc']["source$rule"] -and ( $Source -cmatch $aryMainConf['service_desc']["source$rule"] )) {
$nagvars['service'] = $aryMainConf['service_desc']["desc$rule"]
break
}
if($aryMainConf['service_desc']["alert$rule"] -and ( $AlertDescription -cmatch $aryMainConf['service_desc']["alert$rule"] )) {
$nagvars['service'] = $aryMainConf['service_desc']["desc$rule"]
break
}
}
}
}
# Trace logging
if ($aryMainConf['main']['trace_mode_enabled'] -eq 1) {
logger("hostname = "+$nagvars['hostname'])
logger("service_desc = "+$nagvars['service'])
logger("state = "+$nagvars['state'])
}
if( $nagvars['service'] -eq 'IGNORE' ) {
# We dont log this
if ($aryMainConf['main']['trace_mode_enabled'] -eq 1) {
logger("Not sending to Nagios due to IGNORE configuration")
}
exit 0
}
if( $nagvars['hostname'] -eq 'microsoft.systemcenter.agentwatchersgroup' ) {
# We dont log this
logger("Not sending to Nagios due to invalid hostname")
exit 0
}
# Send alert to Nagios
if( $nagvars['state'] -gt 0 -or $aryMainConf['main']['errors_only'] -ne 1 ) {
# Verify
if( (!$nagvars['nrdpurl']) -or (!$nagvars['nrdptoken']) ) {
logger( "No NRDP URL and Token provided in ini file." )
exit 2
}
# Build XML
$xmlPost = generate_alert_xml $nagvars
# Send
$rv = send_alert_to_nagios $xmlPost $nagvars
} elseif ($aryMainConf['main']['trace_mode_enabled'] -eq 1) {
logger("Not sending to Nagios as errors_only=1 and this is status 0")
}
exit 0