Discovers Sites, S2S Interfaces and BGP Peers

Microsoft.Windows.RemoteAccess.MultiTenant.2012.R2.Discover.Sites (Discovery)

Element properties:

TargetMicrosoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.RemoteAccessServer
EnabledTrue
Frequency3600
RemotableFalse

Object Discovery Details:

Discovered Classes and their attribuets:
  • Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer
    • PeerName
    • BgpIdentifier
    • IPv6Routing
    • LocalIPv6Address
    • DefaultGatewayRouting
    • CompareMEDAcrossASN
    • LocalIPAddress
    • PeerIPAddress
    • LocalASN
    • PeerASN
    • OperationMode
    • PeeringMode
    • Weight
    • HoldTimeSec
    • IdleHoldTimeSec
    • IngressPolicyList
    • EgressPolicyList
    • MaxAllowedPrefix
    • TcpConnectionEstablished
    • TcpConnectionClosed
    • IPv4Subnets
    • IPv6Subnets
    • ServerName
    • TenantName
    • RoutingDomain
    • RoutingDomainID
    • DisplayName
  • Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface
    • Name
    • Destination
    • AdminStatus
    • IPv4Subnet
    • IPv6Subnet
    • Protocol
    • EncryptionType
    • AuthenticationMethod
    • EapMethod
    • CertificateName
    • UserName
    • ResponderAuthenticationMethod
    • NumberOfTries
    • RetryInterval
    • SADataSizeForRenegotiation
    • SALifeTime
    • NetworkOutageTime
    • IdleDisconnect
    • InternalIPv4
    • InternalIPv6
    • PromoteAlternate
    • LastError
    • UnReachabilityReasons
    • CustomPolicy
    • AuthenticationTransformConstants
    • DHGroup
    • CipherTransformConstants
    • EncryptionMethod
    • IntegrityCheckMethod
    • PfsGroup
    • ServerName
    • TenantName
    • RoutingDomain
    • RoutingDomainID
  • Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.Site
    • IPv4Subnets
    • IPv6Subnets
    • SiteKey
    • ServerName
    • TenantName
    • RoutingDomain
    • RoutingDomainID
    • DisplayName
Discovered relationships and their attribuets:

Member Modules:

ID Module Type TypeId RunAs 
PSDiscoverSites DataSource Microsoft.Windows.TimedPowerShell.DiscoveryProvider Default

Source Code:

<Discovery ID="Microsoft.Windows.RemoteAccess.MultiTenant.2012.R2.Discover.Sites" Target="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.RemoteAccessServer" Enabled="true" ConfirmDelivery="false" Remotable="true" Priority="Normal">
<Category>Discovery</Category>
<DiscoveryTypes>
<DiscoveryClass TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.Site">
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.Site" PropertyID="IPv4Subnets"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.Site" PropertyID="IPv6Subnets"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.Site" PropertyID="SiteKey"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.TenentComponents" PropertyID="ServerName"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.TenentComponents" PropertyID="TenantName"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.TenentComponents" PropertyID="RoutingDomain"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.TenentComponents" PropertyID="RoutingDomainID"/>
<Property TypeID="System!System.Entity" PropertyID="DisplayName"/>
</DiscoveryClass>
<DiscoveryClass TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer">
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer" PropertyID="PeerName"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer" PropertyID="BgpIdentifier"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer" PropertyID="IPv6Routing"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer" PropertyID="LocalIPv6Address"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer" PropertyID="DefaultGatewayRouting"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer" PropertyID="CompareMEDAcrossASN"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer" PropertyID="LocalIPAddress"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer" PropertyID="PeerIPAddress"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer" PropertyID="LocalASN"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer" PropertyID="PeerASN"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer" PropertyID="OperationMode"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer" PropertyID="PeeringMode"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer" PropertyID="Weight"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer" PropertyID="HoldTimeSec"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer" PropertyID="IdleHoldTimeSec"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer" PropertyID="IngressPolicyList"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer" PropertyID="EgressPolicyList"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer" PropertyID="MaxAllowedPrefix"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer" PropertyID="TcpConnectionEstablished"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer" PropertyID="TcpConnectionClosed"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer" PropertyID="IPv4Subnets"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer" PropertyID="IPv6Subnets"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.TenentComponents" PropertyID="ServerName"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.TenentComponents" PropertyID="TenantName"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.TenentComponents" PropertyID="RoutingDomain"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.TenentComponents" PropertyID="RoutingDomainID"/>
<Property TypeID="System!System.Entity" PropertyID="DisplayName"/>
</DiscoveryClass>
<DiscoveryClass TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface">
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="Name"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="Destination"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="AdminStatus"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="IPv4Subnet"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="IPv6Subnet"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="Protocol"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="EncryptionType"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="AuthenticationMethod"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="EapMethod"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="CertificateName"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="UserName"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="ResponderAuthenticationMethod"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="NumberOfTries"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="RetryInterval"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="SADataSizeForRenegotiation"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="SALifeTime"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="NetworkOutageTime"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="IdleDisconnect"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="InternalIPv4"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="InternalIPv6"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="PromoteAlternate"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="LastError"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="UnReachabilityReasons"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="CustomPolicy"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="AuthenticationTransformConstants"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="DHGroup"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="CipherTransformConstants"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="EncryptionMethod"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="IntegrityCheckMethod"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface" PropertyID="PfsGroup"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.TenentComponents" PropertyID="ServerName"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.TenentComponents" PropertyID="TenantName"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.TenentComponents" PropertyID="RoutingDomain"/>
<Property TypeID="Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.TenentComponents" PropertyID="RoutingDomainID"/>
</DiscoveryClass>
<DiscoveryRelationship TypeID="Microsoft.Windows.RemoteAccess.MultiTenant.2012.R2.Tenant.Hosts.Site"/>
<DiscoveryRelationship TypeID="Microsoft.Windows.RemoteAccess.MultiTenant.2012.R2.Site.Hosts.BgpPeer"/>
<DiscoveryRelationship TypeID="Microsoft.Windows.RemoteAccess.MultiTenant.2012.R2.Site.Hosts.S2SInterface"/>
</DiscoveryTypes>
<DataSource ID="PSDiscoverSites" TypeID="Windows!Microsoft.Windows.TimedPowerShell.DiscoveryProvider">
<IntervalSeconds>3600</IntervalSeconds>
<SyncTime/>
<ScriptName>DiscoverSites.ps1</ScriptName>
<ScriptBody><Script>param($sourceId,$managedEntityId,$computerName)

$EventLog = new-object System.Diagnostics.EventLog('Application')
$EventLog.MachineName = "."
$EventLog.Source = "SitesDiscovery"

$api = new-object -comObject 'MOM.ScriptAPI'
$discoveryData = $api.CreateDiscoveryData(0, $sourceId, $managedEntityId)

function Is-ValidIP
{
Param(
[Parameter(Mandatory=$True)]
[string]
$IpAddresses
)
try
{
$ipObj = [System.Net.IPAddress]::parse($IpAddresses)
$isValid = ([System.Net.IPAddress]::tryparse([string]$IpAddresses, [ref]$ipObj))
}
catch
{
$isValid = $false;
}
return $isValid
}

function Get-Subnet($S2SInterface, [bool] $IPv4)
{
$TriggerSubnets = $Null
$PostTriggerSubnets = $Null
if($IPv4)
{
$TriggerSubnets = $S2SInterface.IPv4Subnet
$PostTriggerSubnets = $S2SInterface.PostConnectionIPv4Subnet
}
else
{
$TriggerSubnets = $S2SInterface.IPv6Subnet
$PostTriggerSubnets = $S2SInterface.PostConnectionIPv6Subnet
}

$Subnets = @()

if($TriggerSubnets -ne $Null)
{
foreach($Subnet in $TriggerSubnets)
{
$Address = $Subnet.Split("/")[0]
$Mask = $Subnet.Split("/")[1].Split(":")[0]
$Prefix = $Address + "/" + $Mask
$Subnets += $Prefix
}
}

if($PostTriggerSubnets -ne $Null)
{
foreach($Subnet in $PostTriggerSubnets)
{
$Address = $Subnet.Split("/")[0]
$Mask = $Subnet.Split("/")[1].Split(":")[0]
$Prefix = $Address + "/" + $Mask
$Subnets += $Prefix
}
}

foreach($InterfaceDestination in $S2SInterface.Destination)
{
if(Is-ValidIP -IpAddresses $InterfaceDestination)
{
$Destination = [System.Net.IPAddress]::Parse($InterfaceDestination)
$DestinationPrefix = ""
if(($Destination.AddressFamily -eq [System.Net.Sockets.AddressFamily]::InterNetwork) -and ($IPv4 -eq $True))
{
$DestinationPrefix = $Destination.IPAddressToString + "/" + "32"
}

if(($Destination.AddressFamily -eq [System.Net.Sockets.AddressFamily]::InterNetworkV6) -and ($IPv4 -eq $false))
{
$DestinationPrefix = $Destination.IPAddressToString + "/" + "128"
}

$Subnets += $DestinationPrefix
}
}

$Subnets = $Subnets | ? { $_ } | sort -Unique

return @($Subnets)
}

#Returns the MASK in IPAddress format, eg /23 for IPv4 will return 255.255.254.0
function Get-IpFromMask
{
Param(
[Parameter(Mandatory=$True)]
[int]
$Mask,
[Parameter(Mandatory=$True)]
[bool]
$IPv4
)

[System.Byte[]]$maskBytes = @()

if($IPv4 -eq $True)
{
$maskBytes = @(0,0,0,0)
}
else
{
$maskBytes = @(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
}

for($i = 0 ; $i -lt $maskBytes.Count ; $i++)
{
if($i -lt [Math]::Truncate(($Mask / 8)))
{
$maskBytes[$i] = 0xFF
}
else
{
if($i -gt [Math]::Truncate(($Mask / 8)))
{
$maskBytes[$i] = 0
}
else
{
[System.Byte]$val = 0
[System.Byte]$BitMask = 0x80
for($j =0 ; $j -lt $Mask % 8 ; $j++)
{
$val = $val -bor [System.Byte]($BitMask -shr $j)
}
$maskBytes[$i] = $val
}
}
}

return New-Object -TypeName System.Net.IPAddress -ArgumentList (,$maskBytes)
}

# Applies subnet mask on the given IP
function Apply-Mask
{
Param(
[Parameter(Mandatory=$True)]
[IPAddress]
$Ip,
[Parameter(Mandatory=$True)]
[int]
$Mask
)

[System.Net.IPAddress]$MaskIp
if($Ip.AddressFamily -eq [System.Net.Sockets.AddressFamily]::InterNetwork)
{
$MaskIp = Get-IpFromMask -Mask $Mask -IPv4 $True
}
else
{
$MaskIp = Get-IpFromMask -Mask $Mask -IPv4 $False
}

$IpBytes = $Ip.GetAddressBytes()
$MaskBytes = $MaskIp.GetAddressBytes()

for($i = 0 ; $i -lt $IpBytes.Count ; $i++)
{
$IpBytes[$i] = $IpBytes[$i] -band $MaskBytes[$i]
}

return New-Object System.Net.IPAddress -ArgumentList (,$IpBytes)
}

#Returns true if $Subnet2 is in $Subnet1 or vice-versa
function Test-SameSubnet
{
Param(
[Parameter(Mandatory=$True)]
[String] $Prefix1,
[Parameter(Mandatory=$True)]
[String] $Prefix2
)
$Ip1 = $Prefix1.Split("/")[0]
$Ip2 = $Prefix2.Split("/")[0]

$Mask1 = [int]$Prefix1.Split("/")[1]
$Mask2 = [int]$Prefix2.Split("/")[1]

$Mask = $Mask1
if($Mask2 -lt $Mask1)
{
$Mask = $Mask2
}

$Ip1 = Apply-Mask -Ip $Ip1 -Mask $Mask
$Ip2 = Apply-Mask -Ip $Ip2 -Mask $Mask

#.Equals on $Ip1 is not working, so using string comparison instead
return $Ip1.IPAddressToString.Equals($Ip2.IPAddressToString)
}

#The Prefix can be $Null, single prefix or array of prefixes
#Returns true if there is intersection between the two
function Test-PrefixIntersection
{
Param(
[Parameter(Mandatory=$true)]
[AllowNull()]
$Prefix1,
[Parameter(Mandatory=$true)]
[AllowNull()]
$Prefix2
)

#If either is $Null return false
if(($Prefix1 -eq $Null) -or ($Prefix2 -eq $Null))
{
return $False
}

#Both are non $Null
foreach($TempPrefix1 in $Prefix1)
{
foreach($TempPrefix2 in $Prefix2)
{
$IsSameSubnet = Test-SameSubnet -Prefix1 $TempPrefix1 -Prefix2 $TempPrefix2
if($IsSameSubnet)
{
return $True
}
}
}

return $False
}

# Adds a new entry to $Groups, with specified $Subnets, $S2SInterface and $BgpPeer
function Add-NewMemberS2SInterfaceBgpPeerGroup
{
Param(
[Parameter(Mandatory=$true)]
[AllowNull()]
$Groups, # HashTable
[Parameter(Mandatory=$true)]
[AllowNull()]
$IPv4Subnet, # IPv4Subnet to be used as key
[Parameter(Mandatory=$true)]
[AllowNull()]
$IPv6Subnet, # IPv6Subnet to be used as key
[Parameter(Mandatory=$true)]
[AllowNull()]
$S2SInterface, # S2SInterface to be used as value
[Parameter(Mandatory=$true)]
[AllowNull()]
$BgpPeer, # BgpPeer to be used as value
[Parameter(Mandatory=$true)]
[AllowNull()]
$BgpPeerStat # BgpStatistics to be used as value
)

$Name = New-Object -TypeName PSObject
$Name | Add-Member -Name "IPv4Subnet" -Value $IPv4Subnet -MemberType NoteProperty
$Name | Add-Member -Name "IPv6Subnet" -Value $IPv6Subnet -MemberType NoteProperty

$Value = New-Object -TypeName PSObject
$Value | Add-Member -Name "S2SInterface" -Value $S2SInterface -MemberType NoteProperty
$Value | Add-Member -Name "BgpPeer" -Value $BgpPeer -MemberType NoteProperty
$Value | Add-Member -Name "BgpStatistics" -Value $BgpPeerStat -MemberType NoteProperty

try
{
$Groups.Add($Name, $Value)
}
catch [System.Exception]
{
$EventLog.WriteEntry("[SitesDiscovery] Error occured while running Discovery at (" + $computerName + ") in Add-NewMemberS2SInterfaceBgpPeerGroup method" )
$EventLog.WriteEntry("[SitesDiscovery] Error Data: " + $_)
}

return $Groups
}


function Update-S2SInterfaceBgpPeerGroup
{
Param(
[Parameter(Mandatory=$true)]
[AllowNull()]
$Groups, # HashTable
[Parameter(Mandatory=$true)]
[AllowNull()]
$OldSubnet,
[Parameter(Mandatory=$true)]
[AllowNull()]
$IPv4Subnet, # IPv4Subnet to be used as key
[Parameter(Mandatory=$true)]
[AllowNull()]
$IPv6Subnet, # IPv6Subnet to be used as key
[Parameter(Mandatory=$true)]
[AllowNull()]
$S2SInterface, # S2SInterface to be used as value
[Parameter(Mandatory=$true)]
[AllowNull()]
$BgpPeer, # BgpPeer to be used as value
[Parameter(Mandatory=$true)]
[AllowNull()]
$BgpPeerStat # BgpStatistics to be used as value
)

try
{
$Value = $Groups[$OldSubnet]

$S2SInterfaces = @()
$BgpPeers = @()
$BgpPeerStats = @()

if($S2SInterface -ne $Null)
{
$S2SInterfaces += $S2SInterface
}

if($BgpPeer -ne $Null)
{
$BgpPeers += $BgpPeer
}

if($BgpPeerStat -ne $Null)
{
$BgpPeerStats += $BgpPeerStat
}

if($Value.S2SInterface -ne $Null)
{
$S2SInterfaces += $Value.S2SInterface
}

if($Value.BgpPeer -ne $Null)
{
$BgpPeers += $Value.BgpPeer
}

if($Value.BgpStatistics -ne $Null)
{
$BgpPeerStats += $Value.BgpStatistics
}


$IPv4Subnet = @($IPv4Subnet) + @($OldSubnet.IPv4Subnet)
$IPv6Subnet = @($IPv6Subnet) + @($OldSubnet.IPv6Subnet)

$IPv4Subnet = @($IPv4Subnet | ? { $_ } | sort -uniq)
$IPv6Subnet = @($IPv6Subnet | ? { $_ } | sort -uniq)

$Groups.Remove($OldSubnet)
$Groups = Add-NewMemberS2SInterfaceBgpPeerGroup -Groups $Groups -IPv4Subnet $IPv4Subnet -IPv6Subnet $IPv6Subnet -S2SInterface $S2SInterfaces -BgpPeer $BgpPeers -BgpPeerStat $BgpPeerStats
}
catch [System.Exception]
{
$EventLog.WriteEntry("[SitesDiscovery] Error occured while running Discovery at (" + $computerName + ") in Update-S2SInterfaceBgpPeerGroup method" )
$EventLog.WriteEntry("[SitesDiscovery] Error Data: " + $_)
}

return $Groups
}


function Get-S2SInterfaceBgpPeerGroup($S2SInterfaces, $BgpPeers, $BgpStatistics)
{
# Groups, indexed based on common IPv4Subnet/IPv6Subnet
$Groups = @{}

foreach($S2SInterface in $S2SInterfaces)
{
$IPv4Subnet = Get-Subnet -S2SInterface $S2SInterface -IPv4 $true
$IPv6Subnet = Get-Subnet -S2SInterface $S2SInterface -IPv4 $false

if($Groups.Count -eq 0)
{
$Groups = Add-NewMemberS2SInterfaceBgpPeerGroup -Groups $Groups -IPv4Subnet $IPv4Subnet -IPv6Subnet $IPv6Subnet -BgpPeer $Null -S2SInterface $S2SInterface -BgpPeerStat $Null
}
else
{
$Enum = $Groups.GetEnumerator()
$Enum.Reset()
$Found = $false
while($Enum.MoveNext())
{
$Subnet = $Enum.Current.Name
$ValueObj = $Enum.Current.Value

$SameSubnet = Test-PrefixIntersection -Prefix1 $Subnet.IPv4Subnet -Prefix2 $IPv4Subnet
$SameSubnet = $SameSubnet -or (Test-PrefixIntersection -Prefix1 $Subnet.IPv6Subnet -Prefix2 $IPv6Subnet)

if($SameSubnet)
{
$Found = $true
$Groups = Update-S2SInterfaceBgpPeerGroup -Groups $Groups -OldSubnet $Subnet -IPv4Subnet $IPv4Subnet -IPv6Subnet $IPv6Subnet -S2SInterface $S2SInterface -BgpPeer $Null -BgpPeerStat $Null
break
}
}

if($Found -eq $false)
{
$Groups = Add-NewMemberS2SInterfaceBgpPeerGroup -Groups $Groups -IPv4Subnet $IPv4Subnet -IPv6Subnet $IPv6Subnet -BgpPeer $Null -S2SInterface $S2SInterface -BgpPeerStat $Null
}
}
}


foreach($BgpPeer in $BgpPeers)
{
$BgpPeerStat = $BgpStatistics | Where PeerName -eq $BgpPeer.PeerName
$DestinationIp = [System.Net.IPAddress]::Parse($BgpPeer.PeerIPAddress)
$IPv4 = $DestinationIp.AddressFamily -eq [System.Net.Sockets.AddressFamily]::InterNetwork
$DestinationPrefix = ""

if($IPv4)
{
$DestinationPrefix = $BgpPeer.PeerIPAddress + "/" + "32"
}
else
{
$DestinationPrefix = $BgpPeer.PeerIPAddress + "/" + "128"
}

if($Groups.Count -eq 0)
{
if($IPv4)
{
$Groups = Add-NewMemberS2SInterfaceBgpPeerGroup -Groups $Groups -IPv4Subnet $DestinationPrefix -IPv6Subnet $Null -S2SInterface $Null -BgpPeer $BgpPeer -BgpPeerStat $BgpPeerStat
}
else
{
$Groups = Add-NewMemberS2SInterfaceBgpPeerGroup -Groups $Groups -IPv4Subnet $Null -IPv6Subnet $DestinationPrefix -S2SInterface $Null -BgpPeer $BgpPeer -BgpPeerStat $BgpPeerStat
}
}
else
{
[System.Boolean]$SameSubnet = $False
[System.Boolean]$Found = $False

$Enum = $Groups.GetEnumerator()
$Enum.Reset()


while($Enum.MoveNext())
{
$Subnet = $Enum.Current.Name
$ValueObj = $Enum.Current.Value

if($IPv4)
{
$SameSubnet = Test-PrefixIntersection -Prefix1 $Subnet.IPv4Subnet -Prefix2 $DestinationPrefix
if($SameSubnet)
{
$Found = $True
$Groups = Update-S2SInterfaceBgpPeerGroup -Groups $Groups -OldSubnet $Subnet -IPv4Subnet $DestinationPrefix -IPv6Subnet $Null -S2SInterface $Null -BgpPeer $BgpPeer -BgpPeerStat $BgpPeerStat
break
}
}
else
{
$SameSubnet = Test-PrefixIntersection -Prefix1 $Subnet.IPv6Subnet -Prefix2 $DestinationPrefix
if($SameSubnet)
{
$Found = $True
$Groups = Update-S2SInterfaceBgpPeerGroup -Groups $Groups -OldSubnet $Subnet -IPv4Subnet $Null -IPv6Subnet $DestinationPrefix -S2SInterface $Null -BgpPeer $BgpPeer -BgpPeerStat $BgpPeerStat
break
}
}
}

if($Found -eq $False)
{
if($IPv4)
{
$Groups = Add-NewMemberS2SInterfaceBgpPeerGroup -Groups $Groups -IPv4Subnet $DestinationPrefix -IPv6Subnet $Null -S2SInterface $Null -BgpPeer $BgpPeer -BgpPeerStat $BgpPeerStat
}
else
{
$Groups = Add-NewMemberS2SInterfaceBgpPeerGroup -Groups $Groups -IPv4Subnet $Null -IPv6Subnet $DestinationPrefix -S2SInterface $Null -BgpPeer $BgpPeer -BgpPeerStat $BgpPeerStat
}
}
}
}

return @($Groups.Values)
}

function Get-TenantSites
{
Param(
[Parameter(Mandatory=$True)]
[String]
$RoutingDomain,
[Parameter(Mandatory=$True)]
[AllowNull()]
$AllS2SInterfaces
)

$S2SInterfaces = @($AllS2SInterfaces | where RoutingDomain -eq $RoutingDomain)
$BgpPeers = $Null
$BgpStatistics = $Null

try
{
$BgpPeers = Get-BgpPeer -RoutingDomain $RoutingDomain -ErrorAction SilentlyContinue
}
catch
{
$BgpPeers = $Null
}

try
{
if($BgpPeers -ne $Null)
{
$BgpStatistics = Get-BgpStatistics -RoutingDomain $RoutingDomain -ErrorAction SilentlyContinue
}
else
{
$BgpStatistics = $Null
}
}
catch
{
$BgpStatistics = $Null
}

$Sites = Get-S2SInterfaceBgpPeerGroup -S2SInterfaces $S2SInterfaces -BgpPeers $BgpPeers -BgpStatistics $BgpStatistics
return $Sites
}


$RoutingDomains = @(Get-RemoteaccessRoutingdomain)
$allS2SInterfaces = @(Get-VpnS2SInterface)

foreach($TenantRoutingDomain in $RoutingDomains)
{

$routingDomain = $TenantRoutingDomain.RoutingDomain.ToString()
$routingDomainID = $TenantRoutingDomain.RoutingDomainID.Split("{}")[1].ToString()

$Sites = Get-TenantSites -RoutingDomain $routingDomain -AllS2SInterfaces $allS2SInterfaces
try
{
$BgpRouter = Get-BgpRouter -RoutingDomain $routingDomain -ErrorAction SilentlyContinue
}
catch{}

$BgpRoutes = $Null
try
{
$BgpRoutes = Get-BgpRouteInformation -RoutingDomain $routingDomain -ErrorAction SilentlyContinue
}
catch{}

$SiteNo = 0
foreach($Site in $Sites)
{
$S2SInterfaces = $Site.S2SInterface
$BgpPeers = $Site.BgpPeer
$BgpStatistics = $Site.BgpStatistics
$SiteNo = $SiteNo + 1

$S2SDestinations = @((@($S2SInterfaces).Destination)| ? { $_ } | sort -uniq) -join ","
$PeerASNs = @((@($BgpPeers).PeerASN) | ? { $_ } | sort -uniq) -join ","
$PeerNames = @($BgpPeers.PeerName)

$IPv4Subnets = @(((@($S2SInterfaces).IPv4Subnet) + (@($S2SInterfaces).PostConnectionIPv4Subnet)) | ? { $_ } | sort -uniq)
$IPv6Subnets = @(((@($S2SInterfaces).IPv6Subnet) + (@($S2SInterfaces).PostConnectionIPv6Subnet)) | ? { $_ } | sort -uniq)

$IPv4SubnetsTemp = @()
$IPv6SubnetsTemp = @()
foreach($IPv4Subnet in $IPv4Subnets)
{
$IPv4SubnetTemp = ($IPv4Subnet.Split("/")[0]) + "/" + ($IPv4Subnet.Split("/")[1].Split(":")[0])
$IPv4SubnetsTemp += $IPv4SubnetTemp
}
foreach($IPv6Subnet in $IPv6Subnets)
{
$IPv6SubnetTemp = ($IPv6Subnet.Split("/")[0]) + "/" + ($IPv6Subnet.Split("/")[1].Split(":")[0])
$IPv6SubnetsTemp += $IPv6SubnetTemp
}

$IPv4Subnets = $IPv4SubnetsTemp
$IPv6Subnets = $IPv6SubnetsTemp

$SiteBgpRoutes = $BgpRoutes | ? {$PeerNames -Contains $_.LearnedFromPeer}
foreach($SiteBgpRoute in $SiteBgpRoutes)
{
$IPv4 = ([System.Net.IPAddress]::Parse($SiteBgpRoute.Network.Split("/")[0])).AddressFamily -eq [System.Net.Sockets.AddressFamily]::InterNetwork
if($IPv4)
{
$IPv4Subnets += $SiteBgpRoute.Network
}
else
{
$IPv6Subnets += $SiteBgpRoute.Network
}
}
$IPv4Subnets = @($IPv4Subnets | ? { $_ } | sort -uniq) -join ","
$IPv6Subnets = @($IPv6Subnets | ? { $_ } | sort -uniq) -join ","

#Create the tenant instance. This is just to ensure that there the below objects doesnt get dropped if tenant is already discovered.
#The parameters will be filled when tenant discovery happens next time.
$rd = $discoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.Tenant']$")
$rd.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $computerName)
$rd.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", $routingDomain.ToString())
$rd.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.Tenant']/ServerName$", $computerName)
$rd.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.Tenant']/TenantName$", $routingDomain)
$rd.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.Tenant']/RoutingDomain$", $routingDomain)
$rd.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.Tenant']/RoutingDomainID$", $routingDomainID)
$rd.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.RemoteAccessServer']/ServerName$", $computerName)
$discoveryData.AddInstance($rd)

$siteDiscovery = $discoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.Site']$")
$siteDiscovery.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $computerName)
$siteDiscovery.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", "Site" + $SiteNo + " (" + $routingDomain + ")")
$siteDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.TenentComponents']/ServerName$", $computerName)
$siteDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.TenentComponents']/TenantName$", $routingDomain)
$siteDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.TenentComponents']/RoutingDomain$", $routingDomain)
$siteDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.TenentComponents']/RoutingDomainID$", $routingDomainID)
$siteDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.Tenant']/TenantName$", $routingDomain )
$siteDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.RemoteAccessServer']/ServerName$", $computerName)


$siteKey = ((@($S2SInterfaces).Name) -join ",") + "_" + ((@($BgpPeers).PeerName) -join ",")
$siteDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.Site']/SiteKey$", $siteKey )
$siteDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.Site']/S2SEndPoints$", $S2SDestinations )
$siteDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.Site']/ASNs$", $PeerASNs )
$siteDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.Site']/IPv4Subnets$", $IPv4Subnets )
$siteDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.Site']/IPv6Subnets$", $IPv6Subnets )

$discoveryData.AddInstance( $siteDiscovery)

foreach($S2SInterface in $S2SInterfaces)
{
$S2Sdestination =((@($S2SInterface.Destination)) -join ",")
$S2SInterfaceDiscovery = $discoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']$")

#Common Properties
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $computerName)
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", "S2SInterface (" + $S2SInterface.Name + ")")
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.TenentComponents']/ServerName$", $computerName)
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.TenentComponents']/TenantName$", $routingDomain)
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.TenentComponents']/RoutingDomain$", $routingDomain)
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.TenentComponents']/RoutingDomainID$", $routingDomainID)


#Properties for this interface
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/Name$", $S2SInterface.Name)
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/Destination$", ((@($S2SInterface.Destination)) -join ","))
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/AdminStatus$", $S2SInterface.AdminStatus.ToString())
if($S2SInterface.IPv4Subnet -ne $Null)
{
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/IPv4Subnet$", $S2SInterface.IPv4Subnet -join ",")
}
if($S2SInterface.IPv6Subnet -ne $Null)
{
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/IPv6Subnet$", $S2SInterface.IPv6Subnet -join ",")
}
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/Protocol$", $S2SInterface.Protocol)
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/AuthenticationMethod$", $S2SInterface.AuthenticationMethod)
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/EapMethod$", $S2SInterface.EapMethod)
if($S2SInterface.Certificate -ne $Null)
{
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/CertificateName$", $S2SInterface.Certificate.Name)
}
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/UserName$", $S2SInterface.UserName)
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/ResponderAuthenticationMethod$", $S2SInterface.ResponderAuthenticationMethod)
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/NumberOfTries$", $S2SInterface.NumberOfTries.ToString())
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/RetryInterval$", $S2SInterface.RetryInterval.ToString())
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/SADataSizeForRenegotiation$", $S2SInterface.SADataSizeForRenegotiation.ToString())
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/SALifeTime$", $S2SInterface.SALifeTime.ToString())
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/NetworkOutageTime$", $S2SInterface.NetworkOutageTime.ToString())
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/IdleDisconnect$", $S2SInterface.IdleDisconnect.ToString())
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/InternalIPv4$", $S2SInterface.InternalIPv4.ToString())
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/InternalIPv6$", $S2SInterface.InternalIPv6.ToString())
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/PromoteAlternate$", $S2SInterface.PromoteAlternate.ToString())
if($S2SInterface.LastError -ne $Null)
{
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/LastError$", $S2SInterface.LastError.ToString())
}
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/UnReachabilityReasons$", $S2SInterface.UnReachabilityReasons)

$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.Site']/SiteKey$", $siteKey)
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.Tenant']/TenantName$", $routingDomain )
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.RemoteAccessServer']/ServerName$", $computerName)
#$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.MultiTenantRRASService']/ServerName$", $computerName)
$CustomPolicyExists = ($S2SInterface | gm | Where Name -eq CustomPolicy) -ne $null

if($CustomPolicyExists)
{
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/CustomPolicy$", "Enabled")
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/AuthenticationTransformConstants$", $S2SInterface.AuthenticationTransformConstant.ToString())
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/DHGroup$", $S2SInterface.DHGroup.ToString())
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/CipherTransformConstants$", $S2SInterface.CipherTransformConstants.ToString())
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/EncryptionMethod$", $S2SInterface.EncryptionMethod.ToString())
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/IntegrityCheckMethod$", $S2SInterface.IntegrityCheckMethod.ToString())
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/PfsGroup$", $S2SInterface.PFSGroup.ToString())
}
else
{
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/CustomPolicy$", "Disabled")
$S2SInterfaceDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.S2SInterface']/EncryptionType$", $S2SInterface.EncryptionType.ToString())
}

$discoveryData.AddInstance( $S2SInterfaceDiscovery)
}

foreach($BgpPeer in $BgpPeers)
{
$BgpPeerDiscovery = $discoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer']$")
$BgpStat = $BgpStatistics | Where PeerName -eq $BgpPeer.PeerName

#Properties common to all BgpPeers
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", $computerName)
$BgpPeerDiscovery.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", "BGPPeer (" + $BgpPeer.PeerName + ")")
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.TenentComponents']/ServerName$", $computerName)
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.TenentComponents']/TenantName$", $routingDomain)
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.TenentComponents']/RoutingDomain$", $routingDomain)
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.TenentComponents']/RoutingDomainID$", $routingDomainID)

$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer']/BgpIdentifier$", $BgpRouter.BgpIdentifier)
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer']/IPv6Routing$", $BgpRouter.IPv6Routing.ToString())
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer']/LocalIPv6Address$", $BgpRouter.LocalIPv6Address)
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer']/DefaultGatewayRouting$", $BgpRouter.DefaultGatewayRouting.ToString())
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer']/CompareMEDAcrossASN$", $BgpRouter.CompareMEDAcrossASN.ToString())


# This BgpPeer's properties
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer']/PeerName$", $BgpPeer.PeerName)
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer']/LocalIPAddress$", $BgpPeer.LocalIPAddress)
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer']/PeerIPAddress$", $BgpPeer.PeerIPAddress)
if($BgpPeer.LocalASN -eq $Null)
{
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer']/LocalASN$", $BgpRouter.LocalASN.ToString())
}
else
{
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer']/LocalASN$", $BgpPeer.LocalASN.ToString())
}
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer']/PeerASN$", $BgpPeer.PeerASN.ToString())
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer']/OperationMode$", $BgpPeer.OperationMode.ToString())
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer']/PeeringMode$", $BgpPeer.PeeringMode.ToString())
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer']/Weight$", $BgpPeer.Weight.ToString())
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer']/HoldTimeSec$", $BgpPeer.HoldTimeSec.ToString())
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer']/IdleHoldTimeSec$", $BgpPeer.IdleHoldTimeSec.ToString())

if($BgpPeer.IngressPolicyList -ne $Null)
{
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer']/IngressPolicyList$", $BgpPeer.IngressPolicyList -join ",")
}
if($BgpPeer.EgressPolicyList -ne $Null)
{
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer']/EgressPolicyList$", $BgpPeer.EgressPolicyList -join ",")
}
if($BgpPeer.MaxAllowedPrefix -ne $Null)
{
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer']/MaxAllowedPrefix$", $BgpPeer.MaxAllowedPrefix.ToString())
}

if($BgpStat -ne $Null)
{
if($BgpStat.TcpConnectionEstablished -ne $Null)
{
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer']/TcpConnectionEstablished$", $BgpStat.TcpConnectionEstablished.ToString())
}
if($BgpStat.TcpConnectionClosed -ne $Null)
{
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer']/TcpConnectionClosed$", $BgpStat.TcpConnectionClosed.ToString())
}
}

$IPv4Subnets = @()
$IPv6Subnets = @()
$SiteBgpRoutes = $BgpRoutes | Where LearnedFromPeer -eq $BgpPeer.PeerName
foreach($SiteBgpRoute in $SiteBgpRoutes)
{
$IPv4 = ([System.Net.IPAddress]::Parse($SiteBgpRoute.Network.Split("/")[0])).AddressFamily -eq [System.Net.Sockets.AddressFamily]::InterNetwork
if($IPv4)
{
$IPv4Subnets += $SiteBgpRoute.Network
}
else
{
$IPv6Subnets += $SiteBgpRoute.Network
}
}
$IPv4Subnets = @($IPv4Subnets | ? { $_ } | sort -uniq) -join ","
$IPv6Subnets = @($IPv6Subnets | ? { $_ } | sort -uniq) -join ","

$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer']/IPv4Subnets$", $IPv4Subnets)
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.BGPPeer']/IPv6Subnets$", $IPv6Subnets)

$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.Site']/SiteKey$", $siteKey)
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.Tenant']/TenantName$", $routingDomain )
$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.RemoteAccessServer']/ServerName$", $computerName)
#$BgpPeerDiscovery.AddProperty("$MPElement[Name='Microsoft.Windows.RemoteAccess.Multitenant.2012.R2.Class.MultiTenantRRASService']/ServerName$", $computerName)


$discoveryData.AddInstance( $BgpPeerDiscovery)
}
}
}

$discoveryData</Script></ScriptBody>
<Parameters>
<Parameter>
<Name>sourceID</Name>
<Value>$MPElement$</Value>
</Parameter>
<Parameter>
<Name>managedEntityID</Name>
<Value>$Target/Id$</Value>
</Parameter>
<Parameter>
<Name>computerName</Name>
<Value>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</Value>
</Parameter>
</Parameters>
<TimeoutSeconds>900</TimeoutSeconds>
</DataSource>
</Discovery>