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)

No Comments, Be The First!

Your email address will not be published.