Script to import Office 365 IP list to Cisco ASA

I had problem with Office 365 because of firewall, so I wrote script that makes list of all IPs needed for O365 that can be easily imported to Cisco ASA:

# CHANGE PATH
$Path = 'E:'
 
$Report = "$Path\Report.txt"
$date = Get-Date -format "yyyyMMdd"
$dateReport = Get-Date -format "dd.MM.yyyy"
$Link = 'https://support.content.office.net/en-us/static/O365IPAddresses.xml'
$LastFile = Get-Content (Get-ChildItem -Path $Path -Filter "*- o365Rules.txt" | sort CreationTime | select -Last 1).FullName
$ChangeDate = Get-Content $Report
$Last = $ChangeDate[-1].Substring($ChangeDate[-1].Length -10,$ChangeDate[-1].Length - ($ChangeDate[-1].Length -10))
 
try { [xml]$o365IpList = Invoke-RestMethod $Link }
catch  {
    $_ | Out-File "$Path\$date - Errors.txt"
    Add-Content $Report "$dateReport Error!!!"
}
 
if (!(Test-Path "$Path\$date - Errors.txt")) {
    $Result = @()
    $ErrorList = @()
    foreach ($Product in $o365IpList.Products.product) {
            foreach ($Addresslist in $Product.addresslist) {
                if ($Addresslist.type -eq "IPV4") {
                    foreach ($Address in $Addresslist.address) {
                        try {
                            [string]$Parse = $Address
                            [string]$IPAddress = $Parse.Substring(0,$Parse.IndexOf("/"))
                            [string]$Cidr = $Parse.Substring($Parse.IndexOf("/")+1,$Parse.Length - $Parse.IndexOf("/")-1)
                            [int]$Prefix = $Cidr
                            if ($Prefix -eq 32) { [string]$Value = "network-object host $IPAddress" }
                            else {
                                $mask = ([Math]::Pow(2,$Prefix)-1) * [Math]::Pow(2,(32-$Prefix))
                                $bytes = [BitConverter]::GetBytes([UInt32] $mask)
                                $IPMask = (($bytes.Count-1)..0 | ForEach-Object {[String]$bytes[$_]}) -join "."
                                [string]$Value = "network-object $IPAddress $IPMask"
                            }
                            $Result += $Value.Trim()
                        }
                        catch { $ErrorList += "$Address --> $_" }
                    }
                }
            }
    }
    $Final = ,"object-group network o365Rules" + ($Result | Sort-Object -Unique)
    $Final | ft | Out-File "$Path\o365Rules.txt"
    $Final | ft | Out-File "$Path\$date - o365Rules.txt"
    if ($ErrorList) { 
        $ErrorList | Out-File "$Path\$date - Errors.txt"
        Add-Content $Report "$dateReport Error!!!"
    }
    else { 
        $Missing = @()
        $Changed = ($o365IpList.Products.updated).Split('/')
        $ChangedFormated = "{0}.{1}.{2}" -f $Changed[1],$Changed[0],$Changed[2]
        $Text = "$dateReport OK, last change $ChangedFormated"
        Add-Content $Report $Text
        $Current = $Text.Substring($Text.Length -10,$Text.Length - ($Text.Length -10))
        if (!($Current -eq $Last)) {
            $LatestRules = Get-Content "$Path\$date - o365Rules.txt"
            foreach ($line in $LatestRules) { if ($LastFile -notcontains $line)      {$Missing += $line} }
            foreach ($line in $LastFile)      { if ($LatestRules -notcontains $line) {$Missing += "no $line"} }
            $FinalMissing = ,"object-group network o365Rules" + ($Missing | sort)
            $FinalMissing | Out-File "$Path\$date - Changes.txt"
        }
    }
}

You need to change path in script (first line) to your custom folder.
You can run this script via Task Scheduler once per day.
First time it will generate few errors (they are safe to ignore, only because there are no files in folder $Path)

It will generate 4 files (date for first 2 files in format YYYYMMDD):

20171009 – Changes (Only changes compared to last report)
20171009 – o365Rules (All IPs in O365 on this date)
o365Rules – Latest report with all IPs [you need to import this file for first time]
Report – Script logging (when was script run, result, last IP change on Office 365)

6 Comments

  1. Thank you, works perfectly.

    Reply
  2. Hi,
    I am a security Guy,
    I will be greatfull, if you please help me to how to run this script and where to run this script.
    Thank you
    Tom

    Reply
  3. Hi, this is working very well, thank you.
    Any advise on how to use this file to import it into Cisco ASA in script way? I don’t feel like manually adding/updating this object group every X weeks…
    Thank you!
    Ori

    Reply
    • You can add lines in this script to import it directly (connect to ASA via SSH) or your network admin can use this file with his own script…

      Reply
  4. This is an awesome script. Saved me a ton of time

    Reply

Your email address will not be published.