Public/Test-Office365Connectivity.ps1
|
function Test-Office365Connectivity { <# .SYNOPSIS Tests reachability of key Microsoft 365 service endpoints for the active environment. .DESCRIPTION Sends a lightweight HTTP GET to each service endpoint and reports whether it is reachable. An HTTP response of any status code (2xx–4xx) is treated as reachable — it proves the host is alive and responding. Timeouts and DNS failures are reported as unreachable. Useful for diagnosing proxy, firewall, or DNS issues before attempting to connect to a service. The SharePoint Online endpoint is skipped when no tenant is configured in the current session. .EXAMPLE Test-Office365Connectivity Tests all endpoints for the currently configured environment and displays results. .EXAMPLE Test-Office365Connectivity | Where-Object { -not $_.Reachable } Displays only the unreachable endpoints. #> [CmdletBinding()] param() # ── Resolve environment-specific endpoints ──────────────────────────────── $local:authBase = $script:myOffice365Services['AzureADAuthorizationEndpointUri'] # Strip to just the scheme+host for a clean HEAD-style test $local:authEndpoint = if ($local:authBase) { try { ([uri]$local:authBase).GetLeftPart([UriPartial]::Authority) } catch { $local:authBase } } else { 'https://login.microsoftonline.com' } $local:exoRaw = $script:myOffice365Services['ConnectionEndpointUri'] $local:exoEndpoint = if ($local:exoRaw) { try { ([uri]$local:exoRaw).GetLeftPart([UriPartial]::Authority) } catch { $local:exoRaw } } else { 'https://outlook.office365.com' } $local:tenant = $script:myOffice365Services['Office365Tenant'] $local:spoEndpoint = if ($local:tenant) { 'https://{0}.sharepoint.com' -f $local:tenant } else { $null } $local:endpoints = [ordered]@{ 'Entra ID / Auth' = $local:authEndpoint 'Microsoft Graph' = 'https://graph.microsoft.com' 'Exchange Online' = $local:exoEndpoint 'SharePoint Online' = $local:spoEndpoint 'Microsoft Teams' = 'https://teams.microsoft.com' 'Azure Information Protection' = 'https://api.aadrm.com' } # ── Test each endpoint ──────────────────────────────────────────────────── foreach ($local:svcName in $local:endpoints.Keys) { $local:url = $local:endpoints[$local:svcName] if (-not $local:url) { [PSCustomObject][ordered]@{ Service = $local:svcName Endpoint = '(skipped — tenant name not configured)' Reachable = $null StatusCode = $null Details = 'Set tenant via Get-Office365Credential or Get-Office365Tenant' } continue } $local:reachable = $false $local:statusCode = $null $local:details = '' try { $local:response = Invoke-WebRequest -Uri $local:url -Method Get ` -UseBasicParsing -TimeoutSec 10 -ErrorAction Stop $local:statusCode = $local:response.StatusCode $local:reachable = $true } catch [System.Net.WebException] { # PS5: a WebException with a response still means the host answered $local:webEx = $_.Exception if ($local:webEx.Response) { $local:statusCode = [int]$local:webEx.Response.StatusCode $local:reachable = $true } else { $local:details = $local:webEx.Message } } catch [Microsoft.PowerShell.Commands.HttpResponseException] { # PS7: non-2xx responses throw HttpResponseException — the host answered $local:statusCode = [int]$_.Exception.Response.StatusCode $local:reachable = $true } catch { $local:details = $_.Exception.Message } [PSCustomObject][ordered]@{ Service = $local:svcName Endpoint = $local:url Reachable = $local:reachable StatusCode = $local:statusCode Details = $local:details } } } |