Get all Microsoft IP and FQDNs for their services

When you are in an environment with strict internet access, you need to figure out what to open to what destination for Microsoft services like Exchange Online, Teams, Endpoint Manager, and so on. Microsoft publishes this on their website but in the blog post, I would like to show you a nice way of outputting that information in an Out-GridView or a CSV file.

How the script works

It downloads the information from a Microsoft link that Microsoft maintains that contains all IP addresses and FQDNs with their TCP or UDP ports, after downloading it converts it from JSON to an object. Afterward, it displays the information in an Out-GridView Windows for easy sorting and filtering (You can copy your selection in the window with CTRL-C) or to a CSV if you use the CSVPath parameter.

Running the script

When running it without any parameters, it looks like this:

When running it with the -CSVPath parameter and specifying the output path, example below which saves it to d:\temp\endpoint.csv, it looks like this:

Get-MicrosoftEndpoints -CSVPath d:\temp\endpoints.csv

The script

Below is the script, you can add it to your PowerShell profile by:

notepad $profile
add '. c:\scripts\get-microsoftendpoints.ps1'
quit/save and start a new PowerShell session
function Get-MicrosoftEndpoints {
    param (      
        [parameter(parameterSetName = "CSV")][string]$CSVPath
    )
    
    #Hide download progress, get current JSON url, retrieve all Endpoints and Convert it from JSON format
    $ProgressPreference = "SilentlyContinue"
    try {
        $site = Invoke-WebRequest -Uri 'https://learn.microsoft.com/en-us/microsoft-365/enterprise/urls-and-ip-address-ranges?view=o365-worldwide' -UseBasicParsing
        $jsonlink = ($site.Links | where-Object OuterHTML -match 'JSON formatted').href
    }
    catch {
        Write-Warning ("Error downloading JSON file, please check if https://learn.microsoft.com/en-us/microsoft-365/enterprise/urls-and-ip-address-ranges?view=o365-worldwide is accessible")
        return 
    }

    try {
        $Endpoints = Invoke-WebRequest -Uri $jsonlink -ErrorAction Stop | ConvertFrom-Json
        Write-Host ("Downloading worldwide Microsoft Endpoints") -ForegroundColor Green
    }
    catch {
        Write-Warning ("Error downloading worldwide Microsoft Endpoints, please check if $($jsonlink) is accessible")
        return
    }
    
    Write-Host ("Processing items...") -ForegroundColor Green
    $Total = foreach ($Endpoint in $Endpoints) {
        #Check if IPs are available for the Endpoint, set to not available if not
        if (-not $Endpoint.ips) {
            $IPaddresses = 'Not available'
        }
        else {
            $IPaddresses = $Endpoint.ips.split(' ') -join ', '
        }

        #Check if TCP ports are available for the Endpoint, set to not available if not
        if (-not $Endpoint.tcpPorts) {
            $TCPPorts = 'Not available'
        }
        else {
            $TCPPorts = $Endpoint.TCPPorts.split(',') -join ', '
        }
            
        #Check if UDP ports are available for the Endpoint, set to not available if not
        if (-not $Endpoint.udpPorts) {
            $UDPPorts = 'Not available'
        }
        else {
            $UDPPorts = $Endpoint.udpPorts.split(',') -join ', '
        }

        #Check if there are notes for the Endpoint, set to not available if not
        if (-not $Endpoint.notes) {
            $Notes = 'Not available'
        }
        else {
            $Notes = $Endpoint.Notes
        }

        #Check if URLs are available for the Endpoint, set to not available if not
        if (-not $Endpoint.urls) {
            $URLlist = 'Not available'
        }
        else {
            $URLlist = $Endpoint.urls -join ', '
        }
                        
        [PSCustomObject]@{
            serviceArea            = $Endpoint.serviceArea
            serviceAreaDisplayName = $Endpoint.serviceAreaDisplayName
            urls                   = $URLlist
            ips                    = $IPaddresses
            tcpPorts               = $TCPPorts
            udpPorts               = $UDPPorts
            notes                  = $notes
            expressRoute           = $Endpoint.expressRoute
            category               = $Endpoint.Category
            required               = $Endpoint.required
        }
    }

    #Export data to specified $CSVPath if specified
    if ($CSVPath) {
        try {
            New-Item -Path $CSVPath -ItemType File -Force:$true -ErrorAction Stop | Out-Null
            $Total | Sort-Object serviceAreaDisplayName | Export-Csv -Path $CSVPath -Encoding UTF8 -Delimiter ';' -NoTypeInformation
            Write-Host ("Saved results to {0} `nDone!" -f $CSVPath) -ForegroundColor Green
        }
        catch {
            Write-Warning ("Could not save results to {0}" -f $CSVPath)
        }
    }
    else {
        #Export to Out-Gridview
        Write-Host ("Exporting results to Out-GridView `nDone!") -ForegroundColor Green
        $Total | Sort-Object serviceAreaDisplayName | Out-GridView -Title 'Microsoft Endpoints Worldwide'
    }
}

Download the script(s) from GitHub here

7 thoughts on “Get all Microsoft IP and FQDNs for their services

  1. Pingback: PowerShell is fun :) Test if Microsoft services TCP ports are accessible

  2. Pingback: PowerShell is fun :) Overview of 2022 posts

  3. you have a typo on the suggestion for the profile edit. “add ‘. c:\scripts\get-microsoftendpoints.csv’” should presumably be add ‘. c:\scripts\get-microsoftendpoints.ps1’

Leave a Reply

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