internal/functions/Test-MicrosoftIP.ps1
<#
.SYNOPSIS Determine if an IP listed in on the O365 XML list .DESCRIPTION Determine if an IP listed in on the O365 XML list This function uses the System.Net.IPNetwork.dll to parse the IP Addresses. This is the only use for this DLL .PARAMETER IPtoTest IP that is being tested against the Microsoft IP List .PARAMETER Type Checking for ipv 6 or ipv4 .EXAMPLE Test-MicrosoftIP Test wether or not the IP retrieved is a Microsoft IP .INPUTS Inputs (if any) .OUTPUTS Output (if any) .NOTES General notes #> Function Test-MicrosoftIP { param ( [Parameter(Mandatory = $true)] [string]$IPToTest, [Parameter(Mandatory = $true)] [string]$Type ) # Check if we have imported all of our IP Addresses if ($null -eq $MSFTIPList) { Out-Logfile "Building MSFTIPList" # Load our networking dll pulled from https://github.com/lduchosal/ipnetwork [string]$dll = join-path (Split-path (((get-module Hawk)[0]).path) -Parent) "\bin\System.Net.IPNetwork.dll" $Error.Clear() Out-LogFile ("Loading Networking functions from " + $dll) [Reflection.Assembly]::LoadFile($dll) if ($Error.Count -gt 0) { Out-Logfile "[WARNING] - DLL Failed to load can't process IPs" Return "Unknown" } $Error.clear() $MSFTJSON = (Invoke-WebRequest -uri ("https://endpoints.office.com/endpoints/Worldwide?ClientRequestId=" + (new-guid).ToString())).content | ConvertFrom-Json if ($Error.Count -gt 0) { Out-Logfile "[WARNING] - Unable to retrieve JSON file" Return "Unknown" } # Make sure our arrays are null [array]$ipv6 = $Null [array]$ipv4 = $Null # Put all of the IP addresses from the JSON into a simple array Foreach ($Entry in $MSFTJSON) { $IPList += $Entry.IPs } # Throw out duplicates $IPList = $IPList | Select-Object -Unique # Add the IP Addresses into either the v4 or v6 arrays Foreach ($ip in $IPList) { if ($ip -like "*.*") { $ipv4 += $ip } else { $ipv6 += $ip } } Out-LogFile ("Found " + $ipv6.Count + " unique MSFT IPv6 address ranges") Out-LogFile ("Found " + $ipv4.count + " unique MSFT IPv4 address ranges") # New up using our networking dll we need to pull these all in as network objects foreach ($ip in $ipv6) { [array]$ipv6objects += [System.Net.IPNetwork]::Parse($ip) } foreach ($ip in $ipv4) { [array]$ipv4objects += [System.Net.IPNetwork]::Parse($ip) } # Now create our output object $output = $Null $output = New-Object -TypeName PSObject $output | Add-Member -MemberType NoteProperty -Value $ipv6objects -Name IPv6Objects $output | Add-Member -MemberType NoteProperty -Value $ipv4objects -Name IPv4Objects # Create a global variable to hold our IP list so we can keep using it Out-LogFile "Creating global variable `$MSFTIPList" New-Variable -Name MSFTIPList -Value $output -Scope global } # Determine if we have an ipv6 or ipv4 address if ($Type -like "ipv6") { # Compare to the IPv6 list [int]$i = 0 [int]$count = $MSFTIPList.ipv6objects.count - 1 # Compare each IP to the ip networks to see if it is in that network # If we get back a True or we are beyond the end of the list then stop do { # Test the IP $parsedip = [System.Net.IPAddress]::Parse($IPToTest) $test = [System.Net.IPNetwork]::Contains($MSFTIPList.ipv6objects[$i], $parsedip) $i++ } until(($test -eq $true) -or ($i -gt $count)) # Return the value of test true = in MSFT network Return $test } else { # Compare to the IPv4 list [int]$i = 0 [int]$count = $MSFTIPList.ipv4objects.count - 1 # Compare each IP to the ip networks to see if it is in that network # If we get back a True or we are beyond the end of the list then stop do { # Test the IP $parsedip = [System.Net.IPAddress]::Parse($IPToTest) $test = [System.Net.IPNetwork]::Contains($MSFTIPList.ipv4objects[$i], $parsedip) $i++ } until(($test -eq $true) -or ($i -gt $count)) # Return the value of test true = in MSFT network Return $test } } |