Created
August 23, 2019 18:55
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[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