Parsing Office365 IP addreses

I need some help to get the list of addresses out of Office365 lists.

I got this going:

$O365IPAddresses = "https://support.content.office.net/en-us/static/O365IPAddresses.xml"
[XML]$O365 = Invoke-WebRequest -Uri $O365IPAddresses -DisableKeepAlive


ForEach ($Product in $O365.products.product) {
    $GroupName = $Product.Name
    Write-Host "Product Name : $GroupName"
    ForEach ($AddressList in $Product.addresslist) {
        $Type = $AddressList.type
        Write-Host "Type = $Type"
        ForEach ($Address in $AdressList.address) {
            $Address
        } 
    }
}

But need some help to get to the actuall addresses. Preferably in the proper loop so I can refer to the Product names.

Running some test in a different window helped me a but to see this:

PS C:\Users\hvdk> $O365.products.product.addresslist

type address
---- -------
IPv6 {2603:1020:200::682f:a1d8/128, 2603:1020:201::3c4/128, 2603:1030:603::6a/128, 2603:1030:603::72/128...}
IPv4 {13.64.196.27/32, 13.64.198.19/32, 13.64.198.97/32, 13.64.199.41/32...}
URL  {*.aadrm.com, *.activedirectory.windowsazure.com, *.adhybridhealth.azure.com, *.aria.microsoft.com...}
URL  {*.api.skype.com, *.azureedge.net, *.broadcast.skype.com, *.config.skype.com...}
IPv6 {2603:1027::/48, 2603:1029:100::/48, 2603:1037::/48, 2603:1039:100::/48...}
IPv4 {13.64.106.229/32, 13.64.240.95/32, 13.67.56.225/32, 13.67.109.136/32...}
URL  {tasks.office.com, cus-000.tasks.osi.office.net, ea-000.tasks.osi.office.net, eus-zzz.tasks.osi.office.net...}
IPv4 {13.107.6.160/32, 13.107.9.160/32, 23.97.56.236/32, 23.97.78.215/32...}
IPv4 {13.64.106.229/32, 13.64.240.95/32, 13.67.56.225/32, 13.67.109.136/32...}
URL  {*.asm.skype.com, *.azureedge.net, *.cc.skype.com, *.config.skype.com...}
IPv6 {2603:1027::/48, 2603:1029:100::/48, 2603:1037::/48, 2603:1039:100::/48...}
IPv6 {2a01:111:2003::51, 2620:1ec:5::51}
IPv4 {13.67.53.38/32, 13.67.56.73/32, 13.69.159.30/32, 13.75.42.223/32...}
URL  {activation.sls.microsoft.com, ajax.aspnetcdn.com, ajax.microsoft.com, auth.gfx.ms...}
URL  {*.onenote.com, *.msecnd.net, *.microsoft.com, *.office.net...}
IPv4 {13.73.106.160/32, 13.75.158.234/32, 13.78.58.132/32, 13.79.161.29/32...}
URL  {*.assets-yammer.com, *.yammer.com, *.yammerusercontent.com}
IPv4 {13.107.6.158/31, 13.107.9.158/31, 134.170.148.0/22}
IPv6 {2620:1ec:a92::158, 2620:1ec:4::158, 2620:1ec:a92::159, 2620:1ec:4::159}
IPv4 {13.107.6.152/31, 13.107.9.152/31, 13.107.18.10/31, 13.107.19.10/31...}
URL  {*.outlook.com, *.um.outlook.com, *.store.core.windows.net, *.outlook.office.com...}
IPv6 {2603:1006::/40, 2603:1016::/40, 2603:1020:0800::/40, 2603:1026::/40...}
URL  {*.adhybridhealth.azure.com, *.blob.core.windows.net, *.cloudapp.net, *.microsoft.com...}
IPv4 {13.67.50.224/29, 13.71.201.64/26, 13.106.4.128/25, 13.75.48.16/29...}
IPv6 {2603:1020:201::4a0/128, 2603:1020:201::4a1/128, 2603:1020:201::4a2/128, 2603:1020:201::4a3/128...}
URL  {ajax.aspnetcdn.com, amp.azure.net, assets.onestore.ms, az416426.vo.msecnd.net...}
IPv4 {13.69.187.20/32, 13.70.184.242/32, 13.71.155.176/32, 13.75.153.216/32...}
IPv6 {2603:1020:201::37/128, 2603:1020:201:9::c6/128, 2603:1030:1000::1d/128, 2603:1030:f00::17/128...}
URL  {*broadcast.officeapps.live.com, *excel.officeapps.live.com, *onenote.officeapps.live.com, *powerpoint.officeap...
URL  {*.log.optimizely.com, *.sharepoint.com, *.sharepointonline.com, *.svc.ms...}
IPv6 {2620:1ec:a92::150/128, 2620:1ec:4::150/128, 2620:1ec:6::129/128, 2a01:111:f402::/48...}
IPv4 {13.107.6.150/31, 13.107.6.168/32, 13.107.9.150/31, 13.107.9.168/32...}
IPv4 {13.67.59.89/32, 40.69.150.142/32, 40.85.91.8/32, 104.211.54.99/32...}
IPv6
IPv4 {40.76.22.51/32, 40.76.30.255/32, 40.76.213.143/32, 40.76.216.125/32...}
URL  {sway.com, www.sway.com, eus-www.sway.com, eus-000.www.sway.com...}
IPv6
IPv4
URL  {*.acompli.net, *.appex.bing.com, *.appex-rf.msn.com, *-my.sharepoint.com...}
URL  {*.entrust.net, *.geotrust.com, *.omniroot.com, *.public-trust.com...}
URL  {directory.services.live.com, odc.officeapps.live.com, docs.live.net, roaming.officeapps.live.com...}
IPv4 {23.103.132.0/22, 23.103.136.0/21, 23.103.144.0/20, 23.103.198.0/23...}
IPv6 {2a01:111:f400:7c00::/54, 2a01:111:f400:fc00::/54, 2a01:111:f403::/48}

I can manager splitting the address from the masklength field.

Each of those “address” items should be a distinct property. That is, if you took your $Address variable (if I’m following the code correctly)…

ForEach ($Addr in $Address) {}

You could get each one individually.

Just tried that but there is nothing shown there. It seems the manual test overload some table:

PS C:\Users\hvdk> $O365.products.product.addresslist.address

OverloadDefinitions
-------------------
System.Object&, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 Address(int )

Or am I missing something special in regard to the OverloadDefinitions?

If I use:

$O365IPAddresses = "https://support.content.office.net/en-us/static/O365IPAddresses.xml"
[XML]$O365 = Invoke-WebRequest -Uri $O365IPAddresses -DisableKeepAlive


ForEach ($Product in $O365.products.product) {
    $GroupName = $Product.Name
    Write-Host "Product Name : $GroupName"
    ForEach ($AddressList in $Product.addresslist) {
        $Type = $AddressList.type
        Write-Host "Type = $Type"
        ForEach ($Address in $AdressList.address) {
            ForEach ($IPAddress in $Address) {
                $IPAddress
            }
        } 
    }
}

It shows:

Product Name : o365
Type = IPv6
Type = IPv4
Type = URL
Product Name : LYO
Type = URL
Type = IPv6
Type = IPv4
Product Name : Planner
Type = URL
Type = IPv4
Product Name : Teams
Type = IPv4
Type = URL
Type = IPv6
Product Name : ProPlus
Type = IPv6
Type = IPv4
Type = URL
Product Name : OneNote
Type = URL
Type = IPv4
Product Name : Yammer
Type = URL
Type = IPv4
Type = IPv6
Product Name : EXO
Type = IPv4
Type = URL
Type = IPv6
Product Name : Identity
Type = URL
Type = IPv4
Type = IPv6
Product Name : Office365Video
Type = URL
Product Name : WAC
Type = IPv4
Type = IPv6
Type = URL
Product Name : SPO
Type = URL
Type = IPv6
Type = IPv4
Product Name : RCA
Type = IPv4
Type = IPv6
Product Name : Sway
Type = IPv4
Type = URL
Product Name : EX-Fed
Type = IPv6
Type = IPv4
Product Name : OfficeMobile
Type = URL
Product Name : CRLs
Type = URL
Product Name : OfficeiPad
Type = URL
Product Name : EOP
Type = IPv4
Type = IPv6

So there is more to this structure I am not getting.

I’d fall back to the top level thing you get from O355 and pipe it to format-custom, specifying a large depth limit - like 10 or so. It’s a better way to see the raw structure.

It looks like you have a typo in line 11 of your code that’s causing your issue.

You have:

ForEach ($Address in $AdressList.address) { <---You have one "d" in "$AdressList", when you should have two.

It should be:

ForEach ($Address in $AddressList.address) {

When I use the corrected line above in your code, I get:

Product Name : o365
Type = IPv6
2603:1020:200::682f:a1d8/128
2603:1020:201::3c4/128

Type = IPv4
13.64.196.27/32
13.64.198.19/32
13.64.198.97/32

Type = URL
*.aadrm.com
*.activedirectory.windowsazure.com
*.adhybridhealth.azure.com

Etc…

I took your code and turned it into a full function that returns objects instead of the long list of text, in case you’re interested.

https://gist.github.com/miracles1315/41cbcbe2018e1399f09029bee583c634

You’re a GOOD PERSON.

Thanks, Don. I learned from the best. :slight_smile:

Silly me :wink: Such a simple typo. (Mut be language issue)

Happens to me all the time. If only PowerShell could read your mind. :slight_smile: