2019-12-11 10:14:35 -05:00
<#
. SYNOPSIS
Returns interface ip address , which will be used for the host object within the icinga director .
. DESCRIPTION
Get-IcingaNetworkInterface returns the ip address of the interface , which will be used for the host object within the icinga director .
More Information on https : / / github . com / Icinga / icinga-powershell -framework
. FUNCTIONALITY
This module is intended to be used to determine the interface ip address , during kickstart wizard , but will also function standalone .
. EXAMPLE
PS > Get-IcingaNetworkInterface 'icinga.com'
192.168 . 243 . 88
. EXAMPLE
2020-08-04 08:48:32 -04:00
PS > Get-IcingaNetworkInterface '8.8.8.8'
2019-12-11 10:14:35 -05:00
192.168 . 243 . 88
. PARAMETER IP
Used to specify either an IPv4 , IPv6 address or an FQDN .
. INPUTS
System . String
. OUTPUTS
System . String
. LINK
https : / / github . com / Icinga / icinga-powershell -framework
. NOTES
#>
function Get-IcingaNetworkInterface ( )
{
param (
[ string ] $IP
) ;
2019-12-12 08:19:37 -05:00
if ( [ string ] :: IsNullOrEmpty ( $IP ) ) {
2020-05-13 10:53:15 -04:00
Write-IcingaConsoleError 'Please specify a valid IP-Address or FQDN' ;
2019-12-12 08:19:37 -05:00
return $null ;
}
2020-04-17 10:24:25 -04:00
# Ensure that we can still process on older Windows system where
# Get-NetRoute ist not available
if ( ( Test-IcingaFunction 'Get-NetRoute' ) -eq $FALSE ) {
Write-IcingaConsoleWarning 'Your Windows system does not support "Get-NetRoute". A fallback solution is used to fetch the IP of the first Network Interface routing through 0.0.0.0'
return ( Get-IcingaNetworkRoute ) . Interface ;
}
2019-12-11 10:14:35 -05:00
try {
2020-01-15 09:25:10 -05:00
[ array ] $IP = ( [ System.Net.Dns ] :: GetHostAddresses ( $IP ) ) . IPAddressToString ;
2019-12-11 10:14:35 -05:00
} catch {
2020-05-13 10:53:15 -04:00
Write-IcingaConsoleError 'Invalid IP was provided!' ;
2019-12-11 10:14:35 -05:00
return $null ;
}
$IPBinStringMaster = ConvertTo-IcingaIPBinaryString -IP $IP ;
[ hashtable ] $InterfaceData = @ { } ;
$InterfaceInfo = Get-NetRoute ;
$Counter = 0 ;
foreach ( $Info in $InterfaceInfo ) {
$Counter + + ;
2020-01-15 09:25:10 -05:00
$Divide = $Info . DestinationPrefix ;
$IP , $Mask = $Divide . Split ( '/' ) ;
2019-12-11 10:14:35 -05:00
2020-01-15 09:25:10 -05:00
foreach ( $destinationIP in $IPBinStringMaster ) {
[ string ] $Key = '' ;
[ string ] $MaskKey = '' ;
2020-08-04 08:48:32 -04:00
<# IPv4 #>
2020-01-15 09:25:10 -05:00
if ( $destinationIP . name -eq 'IPv4' ) {
if ( $IP -like '*.*' ) {
if ( [ int ] $Mask -lt 10 ) {
$MaskKey = [ string ] :: Format ( '00{0}' , $Mask ) ;
} else {
$MaskKey = [ string ] :: Format ( '0{0}' , $Mask ) ;
2019-12-11 10:14:35 -05:00
}
2020-01-15 09:25:10 -05:00
}
2019-12-11 10:14:35 -05:00
}
2020-08-04 08:48:32 -04:00
<# IPv6 #>
2020-01-15 09:25:10 -05:00
if ( $destinationIP . name -eq 'IPv6' ) {
if ( $IP -like '*:*' ) {
if ( [ int ] $Mask -lt 10 ) {
$MaskKey = [ string ] :: Format ( '00{0}' , $Mask ) ;
} elseif ( [ int ] $Mask -lt 100 ) {
$MaskKey = [ string ] :: Format ( '0{0}' , $Mask ) ;
} else {
$MaskKey = $Mask ;
}
2019-12-11 10:14:35 -05:00
}
2020-01-15 09:25:10 -05:00
}
2019-12-11 10:14:35 -05:00
2020-01-15 09:25:10 -05:00
$Key = [ string ] :: Format ( '{0}-{1}' , $MaskKey , $Counter ) ;
2019-12-11 10:14:35 -05:00
2020-01-15 09:25:10 -05:00
if ( $InterfaceData . ContainsKey ( $Key ) ) {
continue ;
2019-12-11 10:14:35 -05:00
}
2020-01-15 09:25:10 -05:00
$InterfaceData . Add (
$Key , @ {
'Binary IP String' = ( ConvertTo-IcingaIPBinaryString -IP $IP ) . value ;
2020-08-04 09:13:04 -04:00
'Mask' = $Mask ;
'Interface' = $Info . ifIndex ;
2020-01-15 09:25:10 -05:00
}
) ;
2019-12-11 10:14:35 -05:00
}
}
$InterfaceDataOrdered = $InterfaceData . GetEnumerator ( ) | Sort-Object -Property Name -Descending ;
2020-01-15 09:25:10 -05:00
$ExternalInterfaces = @ { } ;
2019-12-11 10:14:35 -05:00
foreach ( $Route in $InterfaceDataOrdered ) {
2020-01-15 09:25:10 -05:00
foreach ( $destinationIP in $IPBinStringMaster ) {
[ string ] $RegexPattern = [ string ] :: Format ( " ^.{{{0}}} " , $Route . Value . Mask ) ;
[ string ] $ToBeMatched = $Route . Value . " Binary IP String " ;
2020-02-07 05:06:57 -05:00
if ( $null -eq $ToBeMatched ) {
continue ;
}
2020-01-15 09:25:10 -05:00
$Match1 = [ regex ] :: Matches ( $ToBeMatched , $RegexPattern ) . Value ;
$Match2 = [ regex ] :: Matches ( $destinationIP . Value , $RegexPattern ) . Value ;
If ( $Match1 -like $Match2 ) {
2020-02-07 05:06:57 -05:00
$ExternalInterface = ( ( Get-NetIPAddress -InterfaceIndex $Route . Value . Interface -AddressFamily $destinationIP . Name -ErrorAction SilentlyContinue ) . IPAddress ) ;
# If no interface was found -> skip this entry
if ( $null -eq $ExternalInterface ) {
continue ;
}
2020-01-15 09:25:10 -05:00
if ( $ExternalInterfaces . ContainsKey ( $ExternalInterface ) ) {
$ExternalInterfaces [ $ExternalInterface ] . count + = 1 ;
} else {
$ExternalInterfaces . Add (
$ExternalInterface ,
@ {
'count' = 1
}
) ;
}
}
}
}
if ( $ExternalInterfaces . Count -eq 0 ) {
foreach ( $destinationIP in $IPBinStringMaster ) {
2020-08-04 08:48:32 -04:00
$ExternalInterface = ( ( Get-NetIPAddress -InterfaceIndex ( Get-NetRoute | Where-Object -Property DestinationPrefix -Like '0.0.0.0/0' ) [ 0 ] . IfIndex -AddressFamily $destinationIP . name ) . IPAddress ) . split ( '%' ) [ 0 ] ;
2020-01-15 09:25:10 -05:00
if ( $ExternalInterfaces . ContainsKey ( $ExternalInterface ) ) {
$ExternalInterfaces [ $ExternalInterface ] . count + = 1 ;
} else {
$ExternalInterfaces . Add (
$ExternalInterface ,
@ {
'count' = 1
}
) ;
}
2020-08-04 08:48:32 -04:00
}
2020-01-15 09:25:10 -05:00
}
2019-12-11 10:14:35 -05:00
2020-04-17 10:24:25 -04:00
$InternalCount = 0 ;
[ array ] $UseInterface = @ ( ) ;
2020-01-15 09:25:10 -05:00
foreach ( $interface in $ExternalInterfaces . Keys ) {
$currentCount = $ExternalInterfaces [ $interface ] . count ;
if ( $currentCount -gt $InternalCount ) {
$InternalCount = $currentCount ;
2020-04-17 10:24:25 -04:00
$UseInterface + = $interface ;
2019-12-11 10:14:35 -05:00
}
}
2020-04-17 10:24:25 -04:00
# In case we found multiple interfaces, fallback to our
# 'route print' function and return this interface instead
if ( $UseInterface . Count -ne 1 ) {
return ( Get-IcingaNetworkRoute ) . Interface ;
}
return $UseInterface [ 0 ] ;
2019-12-12 08:19:37 -05:00
}