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" + $aryNagVars['output'] + "" $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 '<','&lt;' -replace '>','&gt;') } 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