Scanning XML file from internet – O365 Products

Recently I worked on script for checking if IP address found in ADFS dedicated load balancer logs matches the Office 365 products IP address ranges/subntes. List of products and IP address can be found on office support page and to make things easier XML file is also provided – link.

For checking if IP address exists within subnet I let myself use the script from internet:
http://www.gi-architects.co.uk/2016/02/powershell-check-if-ip-or-subnet-matchesfits/


# Using function to check if IP address exists within subnet
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]
}

We have script for checking IP subnets so now we need to get list of Office 365 Products and their IP addresses from XML file. This can be done in both ways – download the file or just check it online:

List of products and their IP ranges:
https://support.office.com/en-us/article/Office-365-URLs-and-IP-address-ranges-8548a211-3fe7-47cb-abb1-355ea5aa88a2?ui=en-US&rs=en-US&ad=US&fromAR=1

XML file from Office support page:
https://support.content.office.net/en-us/static/O365IPAddresses.xml

Write-host "-------------------------------------------------------------------------------"
Write-host Script will gather O365 Products with their IP ranges from office support page
Write-host "-------------------------------------------------------------------------------"

# Get XML File from desktop
#$xml=(Get-Content "C:\temp\O365IPAddresses.xml") 

# Get XML File from internet
$xml=(New-Object System.Net.WebClient).DownloadString("https://support.content.office.net/en-us/static/O365IPAddresses.xml")

# Provide IP number which you want to search
$IP = Read-Host "Please provide IP address"

# Taking names of O365 products
$Products = $xml.products.product

$ComplexArray = @()


# Looping for each products
foreach($Product in $Products){

$IPV4 = ($Product.addresslist | where {$_.type -eq "IPv4"}).address

    if($ipv4){

    $Object = New-Object PSObject 
    $Object | Add-Member Noteproperty "Product name" -Value $Product.name
    $Object | Add-Member Noteproperty "IPV4" -Value $IPV4

    }

$ComplexArray += $Object

}

For every product script will scan the list of IP addresses and if there is a match it will put results in defined hash tables. Additionally script will display colored output in the host.

# Let's define a Pass/Fail for results
$Pass = @()
$Fail = @()

# Scanning for specific IP address
foreach($item in $ComplexArray){

    # Define list of IP ranges
    $ipRanges = $item.IPv4

    # Loop through IP range list
    $ipRanges | ForEach-Object {

        # Define variable for IP range
        $ipRange = $_

        # Check if input IP address matches subnet
        If ((checkSubnet -addr1 $ipRange -addr2 ($ip + "/32")).Condition -eq $True)
        {

        # Colored output in host
            Write-host "MATCH: " -ForegroundColor Yellow -NoNewline
            Write-host "$IP found in product: " -NoNewline
            Write-host $item."Product name" -ForegroundColor green -NoNewline
            Write-host " - Subnet:" $ipRange

            $Object = New-Object PSCustomObject
            $Object | Add-Member -Type NoteProperty -Name "Product Name" -Value $item."Product name"
            $Object | Add-Member -Type NoteProperty -Name "Subnet" -Value $ipRange
            $Fail += $Object
        }
        Else 
        {
            $Object = New-Object PSCustomObject
            $Object | Add-Member -Type NoteProperty -Name "Product Name" -Value $item."Product name"
            $Object | Add-Member -Type NoteProperty -Name "Subnet" -Value $ipRange
            $Pass += $Object
        }
   }
}


   if(!$fail)
   {
   Write-Warning "No matches found"
   }


Output:

Script:
scan-xml

I hope you will find this script useful and see you in the next article 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.