Page 1 of 1

Passing $HOSTADDRESS$ from service to Powershell plugin

Posted: Tue Mar 31, 2015 6:18 am
by WillemDH
Hello,

I seem to be having an issue passing the $HOSTADDRESS$ macro from service to Powershell plugin as an argument. Why don't I retrieve the ip from the server with Powershell? because on Windows failover Clusters, the usual commands to get the active ip address always return the 169.254 address of the failover adapter. So in order to get my script http://exchange.nagios.org/directory/Pl ... ad/details working on failover cluster nodes, I need to pass the ip of the node from Nagios to the Powershell script.

Code: Select all

# Script name:   	check_ms_win_network_load.ps1
# Version:			0.15.03.31
# Created on:    	25/10/2014
# Author:        	D'Haese Willem
# Purpose:       	Checks Microsoft Windows network load for the active adapter.
# On Github:		https://github.com/willemdh/check_ms_win_network_load
# On OutsideIT:		http://outsideit.net/check-ms-win-network-load
# Recent History:       	
#	28/10/2014 => Added perfdata, NeworkStruct
#	10/03/2015 => Testing, rework
#	11/03/2015 => Support for teamed network cards, error handling
#   30/03/2015 => Small change in query for used team member
#	31/03/2015 => Added support for Intel[R] PRO/1000 MT Network Connection 
# Copyright:
#	This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published
#	by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed 
#	in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
#	PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public 
#	License along with this program.  If not, see <http://www.gnu.org/licenses/>.

#Requires –Version 2.0
	
$NetworkStruct = New-Object PSObject -Property @{
    Hostname = [string]'localhost';
	ActiveIp = (((ipconfig.exe | findstr.exe [0-9].\.)[0]).Split()[-1])
    ExitCode = [int]3;
	LinkWarn = [int]0;
	LinkCrit = [int]0;
	Timer = [int]10;
    OutputString = [string]'UNKNOWN: Error processing, no data returned.';
	EnabledNetAdapters = @()
}

#region Functions

Function Initialize-Args {
    Param ( 
        [Parameter(Mandatory=$True)]$Args
    )	
    try {
        For ( $i = 0; $i -lt $Args.count; $i++ ) { 
		    $CurrentArg = $Args[$i].ToString()
            if ($i -lt $Args.Count-1) {
				$Value = $Args[$i+1];
				If ($Value.Count -ge 2) {
					foreach ($Item in $Value) {
						Test-Strings $Item | Out-Null
					}
				}
				else {
	                $Value = $Args[$i+1];
					Test-Strings $Value | Out-Null
				}	                             
            } else {
                $Value = ''
            };

            switch -regex -casesensitive ($CurrentArg) {
                "^(-H|--Hostname)$" {
					if ($Value -ne ([System.Net.Dns]::GetHostByName((hostname.exe)).HostName).tolower() -and $Value -ne 'localhost') {
						& ping.exe -n 1 $Value | out-null
						if($? -eq $true) {
							$NetworkStruct.Hostname = $Value
							$i++
		    			} 
						else {
		    				Write-Host "CRITICAL: Ping to $Value failed! Please provide valid reachable hostname!"
							exit 3
		    			}
					}
					else {
						$NetworkStruct.Hostname = $Value
						$i++
					}
						
                }
				"^(-I|--IPAddress)$" {
                    $NetworkStruct.ActiveIp = $value
                    $i++					
                }               
				"^(-t|--Timer)$" {
	                if (($value -match "^[\d]+$") -and ([int]$value -lt 100)) {
                        $NetworkStruct.Timer = $value
                    } 
					else {
                        throw "Critical treshold should be numeric and less than 100. Value given is $value"
                    }
                    $i++					
                }
                "^(-lw|--LinkWarn)$" {
                    if (($value -match "^[\d]+$") -and ([int]$value -lt 100)) {
                        $NetworkStruct.LinkWarn = $value
                    } else {
                        throw "Link warning treshold should be numeric and less than 100. Value given is $value"
                    }
                    $i++
                }
                "^(-lc|--LinkCrit)$" {
                    if (($value -match "^[\d]+$") -and ([int]$value -lt 100)) {
                         $NetworkStruct.LinkCrit = $value
                    } else {
                        throw "Link critical treshold should be numeric and less than 100. Value given is $value"
                    }
                    $i++
                 }
                "^(-h|--Help)$" {
                    Write-Help
                }
                default {
                    throw "Illegal arguments detected: $_"
                 }
            }
        }
    } catch {
		Write-Host "UNKNOWN: $_"
        Exit $NetworkStruct.ExitCode
	}	
}	

Function Test-Strings {
    Param ( [Parameter(Mandatory=$True)][string]$String )
    # `, `n, |, ; are bad, I think we can leave {}, @, and $ at this point.
    $BadChars=@("``", "|", ";", "`n")
    $BadChars | ForEach-Object {
        If ( $String.Contains("$_") ) {
            Write-Host 'Unknown: String contains illegal characters.'
            Exit $NetStruct.ExitCode
        }
    }
    Return $true
} 

Function Write-Help {
	Write-Host @"
check_ms_win_network_load.ps1:`n`tThis script is designed to monitor Microsoft Windows network load.
Arguments:
    -H  | --Hostname     => Optional hostname of remote system, default is localhost, not yet tested on remote host.
    -I  | --IPAddress    => Ip Address of the system
    -a  | --Adapter      => Adapter to gather load from, not yet implemented.
    -lw | --LinkWarn     => Warning threshold for total link utilisation, not yet implemented.
    -lc | --LinkCrit     => Critical threshold for total link utilisation, not yet implemented.
    -t  | --Timer        => Amount of seconds to gather data.
    -h  | --Help         => Print this help output.
"@
    Exit $TaskStruct.ExitCode;
} 

Function Get-NetworkLoad {
Write-Host "IP: $($NetworkStruct.ActiveIp)"
	$NetworkStruct.EnabledNetAdapters += Get-WmiObject -Class Win32_NetworkAdapter -Filter "AdapterType='Ethernet 802.3'" | ForEach-Object { $_.GetRelated('Win32_NetworkAdapterConfiguration') } |  Where-Object  { ($_.IPEnabled -eq 'True') } | Select-Object Description, Index, IPEnabled, IPAddress, IPConnectionMetric, NetconnectionId, Name, InterfaceIndex, NetconnectionStatus
	if ($NetworkStruct.EnabledNetAdapters.length -gt 1 -and $NetworkStruct.ActiveIp -notlike "169.254.*" ) {
		foreach ($EnabledAdapter in $NetworkStruct.EnabledNetAdapters) {
			foreach ($EnabledAdapterIp in $EnabledAdapter.IpAddress){
				if ($EnabledAdapterIp -eq $NetworkStruct.ActiveIp){
					$ActiveAdapter = $EnabledAdapter
				}
			}
		}
	}
    elseif ($NetworkStruct.ActiveIp -like "169.254.*"){
        Write-Host "169.254"
    }
	else {
		$ActiveAdapter = $NetworkStruct.EnabledNetAdapters[0]
	}
#	$AdapterCleanName = $ActiveAdapter.Description.Substring(9,$ActiveAdapter.Description.Length-9)
	$AdapterCleanName = $ActiveAdapter.Description -replace '#','_'
    if ($AdapterCleanName.startswith('TEAM')) {
        $ActiveTeamedMember = Get-WmiObject Win32_PerfFormattedData_Tcpip_NetworkInterface | Sort BytesTotalPerSec -Descending | Select Name, BytesTotalPerSec -First 1
        $AdapterCleanName = $ActiveTeamedMember.Name
        $AdapterCleanName = $AdapterCleanName -replace '\[','\['
        $AdapterCleanName = $AdapterCleanName -replace '\]','\]'
    }
    else {
        $AdapterCleanName = $AdapterCleanName -replace '\(','\['
        $AdapterCleanName = $AdapterCleanName -replace '\)','\]'
		$AdapterCleanName = $AdapterCleanName -replace '/','_'
    }
    try {
         $AdapterBandwithBytes = (Get-WmiObject Win32_PerfFormattedData_Tcpip_NetworkInterface | Where-Object {$_.name -Match "^$AdapterCleanName$"}  | Select-Object -ExpandProperty CurrentBandwidth) / 8
    }
    catch {
        Write-Host "UNKNOWN: Problem detected while querying bandwith of adapter $AdapterCleanName. Plugin has probably issues detecting the active adapter. Please debug. Error message:  $_"
        Exit $TaskStruct.ExitCode
    }
    if ($AdapterBandwithBytes -eq 0) {
        Write-Host "UNKNOWN: Bandwith of adapter $AdapterCleanName equals 0, which is kind of weird..."
        Exit $TaskStruct.ExitCode
    } 
   
	$StartTime = get-date
	$EndTime   = $StartTime.addSeconds($NetworkStruct.Timer)
	$TimeSpan = New-Timespan $StartTime $EndTime
	$TimeCount = 0
	$AvgLinkUtilTotalValues = @()
	$AvgTotalBytesPerSecValues = @()
	$AvgLinkUtilReceivedValues = @()
	$AvgReceivedBytesPerSecValues = @()
	$AvgLinkUtilSentValues = @()
	$AvgSentBytesPerSecValues = @()

try {      
	while ($TimeSpan -gt 0) 
	{
	 $TimeSpan = New-Timespan $(Get-Date) $EndTime
	 $CurrentBytesPerSec = Get-WmiObject -class Win32_PerfFormattedData_Tcpip_NetworkInterface | Where-Object {$_.Name -Match "^$AdapterCleanName$"} | Select-Object BytesTotalPersec, BytesReceivedPersec, BytesSentPersec 
	 [float]$LinkUtilTotal = ($CurrentBytesPerSec.BytesTotalPerSec / $AdapterBandwithBytes) * 100
	# $LinkUtilTotalValue = '{0:N5}' -f $LinkUtilTotal
	# [int]$LinkUtilReceived = ($CurrentBytesPerSec.BytesReceivedPersec / $AdapterBandwithBytes) * 100
	# $LinkUtilReceivedValue = '{0:N5}' -f $LinkUtilReceived
	# [int]$LinkUtilSent = ($CurrentBytesPerSec.BytesSentPersec / $AdapterBandwithBytes) * 100
	# $LinkUtilSentValue = '{0:N5}' -f $LinkUtilSent
	 $AvgLinkUtilTotalValues += $LinkUtilTotal
	 $AvgTotalBytesPerSecValues += ($CurrentBytesPerSec.BytesTotalPerSec / 1024 / 1024)
	 $AvgReceivedBytesPerSecValues += ($CurrentBytesPerSec.BytesReceivedPerSec / 1024 / 1024)
	 $AvgSentBytesPerSecValues += ($CurrentBytesPerSec.BytesSentPerSec / 1024 / 1024)
	 $TimeCount++ 
	}
}
catch {
     Write-Host "UNKNOWN: Problem detected while querying performance data of adapter $AdapterCleanName. Plugin has probably issues detecting the active adapter. Please debug."
     Exit $TaskStruct.ExitCode
}

	$AvgBandwithTotal = '{0:N5}' -f (($AvgLinkUtilTotalValues | Measure-Object -Average).average)
	$AvgTotalBytesPerSec = '{0:N5}' -f (($AvgTotalBytesPerSecValues | Measure-Object -Average).average)
	$AvgReceivedBytesPerSec = '{0:N5}' -f (($AvgReceivedBytesPerSecValues | Measure-Object -Average).average)
	$AvgSentBytesPerSec = '{0:N5}' -f (($AvgSentBytesPerSecValues | Measure-Object -Average).average)

	$OutputOkString = "OK: $($ActiveAdapter.Description): Avg of $($NetworkStruct.Timer) seconds: {Total Link Utilisation: $AvgBandwithTotal%}{Rate (Total: $AvgTotalBytesPerSec MB/sec)(Received: $AvgReceivedBytesPerSec MB/sec)(Sent: $AvgSentBytesPerSec MB/sec)}"
	$OutputPerfdata = " | 'Total_Rate'=${AvgTotalBytesPerSec}MB/sec 'Received_Rate'=${AvgReceivedBytesPerSec}MB/sec 'Sent_Rate'=${AvgSentBytesPerSec}MB/sec "
	
	$NetworkStruct.OutputString = $OutputOkString + $OutputPerfdata
	$NetworkStruct.ExitCode = 0	
}

#endregion

# Main function 
if($Args.count -ge 1){Initialize-Args $Args}

if ($NetworkStruct.Hostname -eq 'localhost') {
	$NetworkStruct.Hostname = ([System.Net.Dns]::GetHostByName((hostname.exe)).HostName).tolower()
}

Get-NetworkLoad -NetworkStruct $NetworkStruct

Write-Host $NetworkStruct.OutputString

Exit $NetworkStruct.ExitCode
using this command:

Code: Select all

$USER1$/check_nrpe -H $HOSTADDRESS$ -p 5666 -t 120 -c check_ms_win_network_load -a $ARG1$
with this as param 1:

Code: Select all

-I $HOSTADDRESS$
does not work.

Any suggestions? or is this not possible from a service?

Grtz

Willem

Re: Passing $HOSTADDRESS$ from service to Powershell plugin

Posted: Tue Mar 31, 2015 10:38 am
by tmcdonald
What output are you receiving? Have you tried quoting the $HOSTADDRESS$ macro?

Re: Passing $HOSTADDRESS$ from service to Powershell plugin

Posted: Tue Mar 31, 2015 10:40 am
by jdalrymple
Works for me.

Re: Passing $HOSTADDRESS$ from service to Powershell plugin

Posted: Tue Mar 31, 2015 11:56 am
by WillemDH
Single quotes did the trick. SO used to Powershell where single quotes would mean to take %HOSTADRESS% literally.

Thanks. Thread can be closed.