Src/Private/Get-AbrIntuneMicrosoftTunnel.ps1
|
function Get-AbrIntuneMicrosoftTunnel { <# .SYNOPSIS Documents Microsoft Tunnel VPN sites, server configurations, and server health. .DESCRIPTION Collects and reports on: - Tunnel Sites (beta/deviceManagement/microsoftTunnelSites) - Tunnel Configurations per site - Server health and version information .NOTES Version: 0.1.0 Added: v0.2.51 — addresses CRITICAL gap from gap tracker #> [CmdletBinding()] param ( [Parameter(Position = 0, Mandatory)] [string]$TenantId ) begin { Write-PScriboMessage -Message "Collecting Microsoft Tunnel configuration for $TenantId." Show-AbrDebugExecutionTime -Start -TitleMessage 'Microsoft Tunnel' } process { try { Write-Host " - Retrieving Microsoft Tunnel sites..." $TunnelSitesResp = $null try { $TunnelSitesResp = Invoke-MgGraphRequest -Method GET ` -Uri "$($script:GraphEndpoint)/beta/deviceManagement/microsoftTunnelSites" ` -ErrorAction Stop } catch { Write-AbrDebugLog "Tunnel sites unavailable: $($_.Exception.Message)" 'WARN' 'Tunnel' } $TunnelSites = if ($TunnelSitesResp -and $TunnelSitesResp.value) { $TunnelSitesResp.value } else { $null } if ($TunnelSites -and @($TunnelSites).Count -gt 0) { Section -Style Heading2 'Microsoft Tunnel Sites' { Paragraph "The following documents Microsoft Tunnel VPN infrastructure configured in tenant $TenantId." BlankLine $SiteObj = [System.Collections.ArrayList]::new() foreach ($Site in ($TunnelSites | Sort-Object displayName)) { # Fetch servers for this site $serverCount = 0 $serverHealth = '--' try { $ServersResp = $null try { $ServersResp = Invoke-MgGraphRequest -Method GET -Uri "$($script:GraphEndpoint)/beta/deviceManagement/microsoftTunnelSites/$($Site.id)/microsoftTunnelServers" -ErrorAction Stop } catch { } if ($ServersResp -and $ServersResp.value) { $serverCount = @($ServersResp.value).Count $healthStates = $ServersResp.value | ForEach-Object { $_.tunnelServerHealthStatus } if ($healthStates -contains 'unhealthy') { $serverHealth = 'Unhealthy' } elseif ($healthStates -contains 'healthy') { $serverHealth = 'Healthy' } else { $serverHealth = ($healthStates | Select-Object -First 1) } } } catch { } $SiteObj.Add([pscustomobject]([ordered]@{ 'Site Name' = $Site.displayName 'Description' = if ($Site.description) { $Site.description } else { '--' } 'Public Address' = if ($Site.publicAddress) { $Site.publicAddress } else { '--' } 'Servers' = $serverCount 'Server Health' = $serverHealth 'Upgrade Auto' = if ($null -ne $Site.upgradeAutomatically) { if ($Site.upgradeAutomatically) { 'Yes' } else { 'No' } } else { '--' } })) | Out-Null } $SiteParams = @{ Name = "Tunnel Sites - $TenantId"; ColumnWidths = 22, 24, 22, 8, 12, 12 } if ($Report.ShowTableCaptions) { $SiteParams['Caption'] = "- $($SiteParams.Name)" } $SiteObj | Table @SiteParams # Tunnel Configurations try { $TunnelConfigResp = $null try { $TunnelConfigResp = Invoke-MgGraphRequest -Method GET -Uri "$($script:GraphEndpoint)/beta/deviceManagement/microsoftTunnelConfigurations" -ErrorAction Stop } catch { Write-AbrDebugLog "Tunnel configs unavailable: $($_.Exception.Message)" 'WARN' 'Tunnel' } if ($TunnelConfigResp -and $TunnelConfigResp.value -and @($TunnelConfigResp.value).Count -gt 0) { BlankLine Paragraph "Tunnel Server Configurations ($(@($TunnelConfigResp.value).Count)):" BlankLine $CfgObj = [System.Collections.ArrayList]::new() foreach ($Cfg in ($TunnelConfigResp.value | Sort-Object displayName)) { $CfgObj.Add([pscustomobject]([ordered]@{ 'Config Name' = $Cfg.displayName 'Network' = if ($Cfg.network) { $Cfg.network } else { '--' } 'DNS Servers' = if ($Cfg.dnsServers) { $Cfg.dnsServers -join ', ' } else { '--' } 'Split Tunneling' = if ($null -ne $Cfg.splitDNS) { if ($Cfg.splitDNS) { 'Yes' } else { 'No' } } else { '--' } 'Port' = if ($Cfg.listenPort) { "$($Cfg.listenPort)" } else { '--' } })) | Out-Null } $CfgParams = @{ Name = "Tunnel Configurations - $TenantId"; ColumnWidths = 25, 20, 25, 15, 15 } if ($Report.ShowTableCaptions) { $CfgParams['Caption'] = "- $($CfgParams.Name)" } $CfgObj | Table @CfgParams } } catch { } } } else { Write-AbrDebugLog 'No Microsoft Tunnel sites found (feature may not be licensed).' 'INFO' 'Tunnel' } } catch { if (Test-AbrGraphForbidden -ErrorRecord $_) { Write-AbrPermissionError -Section 'Microsoft Tunnel' -RequiredRole 'Intune Service Administrator or Global Administrator' } else { Write-AbrSectionError -Section 'Microsoft Tunnel' -Message "$($_.Exception.Message)" } } } end { Show-AbrDebugExecutionTime -End -TitleMessage 'Microsoft Tunnel' } } |