Skip to content

Instantly share code, notes, and snippets.

@f-bader
Created August 23, 2019 18:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save f-bader/a927791644dd2687f5036f9e9ec86121 to your computer and use it in GitHub Desktop.
Save f-bader/a927791644dd2687f5036f9e9ec86121 to your computer and use it in GitHub Desktop.
Test if a IP address is part of the Office 365 endpoints
[CmdletBinding()]
param (
# IP Address to check against Office 365 Range
[Parameter(Mandatory = $true,
ValueFromPipeline = $true,
Position = 0)]
$IPAddress,
# Port to check
[Parameter(Mandatory = $false,
Position = 1)]
$Port
)
Begin {
#region Functions
# http://www.gi-architects.co.uk/2016/02/powershell-check-if-ip-or-subnet-matchesfits/
# Please note i took inspiration form www.padisetty.com
# The function will check ip to ip, ip to subnet, subnet to ip or subnet to subnet belong to each other and return true or false and the direction of the check
#////////////////////////////////////////////////////////////////////////
function checkSubnet ([string]$addr1, [string]$addr2) {
# Separate the network address and lenght
$network1, [int]$subnetlen1 = $addr1.Split('/')
$network2, [int]$subnetlen2 = $addr2.Split('/')
#Convert network address to binary
[uint32] $unetwork1 = NetworkToBinary $network1
[uint32] $unetwork2 = NetworkToBinary $network2
#Check if subnet length exists and is less then 32(/32 is host, single ip so no calculation needed) if so convert to binary
if ($subnetlen1 -lt 32) {
[uint32] $mask1 = SubToBinary $subnetlen1
}
if ($subnetlen2 -lt 32) {
[uint32] $mask2 = SubToBinary $subnetlen2
}
#Compare the results
if ($mask1 -and $mask2) {
# If both inputs are subnets check which is smaller and check if it belongs in the larger one
if ($mask1 -lt $mask2) {
return CheckSubnetToNetwork $unetwork1 $mask1 $unetwork2
} else {
return CheckNetworkToSubnet $unetwork2 $mask2 $unetwork1
}
} ElseIf ($mask1) {
# If second input is address and first input is subnet check if it belongs
return CheckSubnetToNetwork $unetwork1 $mask1 $unetwork2
} ElseIf ($mask2) {
# If first input is address and second input is subnet check if it belongs
return CheckNetworkToSubnet $unetwork2 $mask2 $unetwork1
} Else {
# If both inputs are ip check if they match
CheckNetworkToNetwork $unetwork1 $unetwork2
}
}
function CheckNetworkToSubnet ([uint32]$un2, [uint32]$ma2, [uint32]$un1) {
$ReturnArray = "" | Select-Object -Property Condition, Direction
if ($un2 -eq ($ma2 -band $un1)) {
$ReturnArray.Condition = $True
$ReturnArray.Direction = "Addr1ToAddr2"
return $ReturnArray
} else {
$ReturnArray.Condition = $False
$ReturnArray.Direction = "Addr1ToAddr2"
return $ReturnArray
}
}
function CheckSubnetToNetwork ([uint32]$un1, [uint32]$ma1, [uint32]$un2) {
$ReturnArray = "" | Select-Object -Property Condition, Direction
if ($un1 -eq ($ma1 -band $un2)) {
$ReturnArray.Condition = $True
$ReturnArray.Direction = "Addr2ToAddr1"
return $ReturnArray
} else {
$ReturnArray.Condition = $False
$ReturnArray.Direction = "Addr2ToAddr1"
return $ReturnArray
}
}
function CheckNetworkToNetwork ([uint32]$un1, [uint32]$un2) {
$ReturnArray = "" | Select-Object -Property Condition, Direction
if ($un1 -eq $un2) {
$ReturnArray.Condition = $True
$ReturnArray.Direction = "Addr1ToAddr2"
return $ReturnArray
} else {
$ReturnArray.Condition = $False
$ReturnArray.Direction = "Addr1ToAddr2"
return $ReturnArray
}
}
function SubToBinary ([int]$sub) {
return ((-bnot [uint32]0) -shl (32 - $sub))
}
function NetworkToBinary ($network) {
$a = [uint32[]]$network.split('.')
return ($a[0] -shl 24) + ($a[1] -shl 16) + ($a[2] -shl 8) + $a[3]
}
#////////////////////////////////////////////////////////////////////////
#endregion
# Generate GUID to query
$GUID = [guid]::NewGuid()
# Retreive
$Office365IPRanges = Invoke-RestMethod -Method Get -UseBasicParsing -Uri "https://endpoints.office.com/endpoints/worldwide?clientrequestid=$GUID&NoIPv6"
$IPAddressInSubnet = $false
$AllIPAddresses = $Office365IPRanges.ips | Select-Object -Unique
}
Process {
foreach ($Subnet in $AllIPAddresses) {
if ( (checkSubnet $IPAddress $Subnet).Condition ) {
Write-Verbose "$IPAddress is part of $Subnet"
$IPAddressInSubnet = $true
break
}
}
if ($IPAddressInSubnet) {
$MatchingServices = $Office365IPRanges | Where-Object { $Subnet -in $_.ips } | Add-Member -NotePropertyName "Subnet" -NotePropertyValue $Subnet -PassThru | Select-Object serviceAreaDisplayName, category, subnet, tcpPorts, required, @{e={"$IPAddress"};n="IPAddress"}
}
if ( $PSBoundParameters.ContainsKey('Port')) {
$MatchingServices = $MatchingServices | Where-Object { $_.tcpPorts -match $port -or $_.udpPorts -match $port }
}
# Output result
if ($MatchingServices) {
$MatchingServices
} else {
Write-Host -ForegroundColor Yellow "Did not find $IPAddress"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment