# 設定編碼以防中文亂碼 [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 Clear-Host # 記錄原本的視窗顏色,以便離開時還原 $originalBg = $host.UI.RawUI.BackgroundColor $originalFg = $host.UI.RawUI.ForegroundColor try { $failStage = $null $isOnline = $false # 快速通道:直接 Ping 外部 DNS (1.1.1.1) 測試網際網路是否暢通 $quickPing = Test-Connection -ComputerName "1.1.1.1" -Count 1 -Quiet if ($quickPing) { $isOnline = $true } else { # 如果快速檢測失敗,才執行詳細的逐層排查 # 步驟 1: 檢查 IP 位址 (只要有一個非 169.254 的 IP 即視為正常) $activeInterfaceIndex = $(Get-NetConnectionProfile -ErrorAction SilentlyContinue | Select-Object -ExpandProperty InterfaceIndex) $allIps = @() if ($activeInterfaceIndex) { $allIps = Get-NetIPAddress -AddressFamily IPv4 -InterfaceIndex $activeInterfaceIndex -ErrorAction SilentlyContinue | Select-Object -ExpandProperty IPAddress } if (-not $allIps) { $allIps = Get-NetIPAddress -AddressFamily IPv4 -ErrorAction SilentlyContinue | Where-Object { $_.IPAddress -ne "127.0.0.1" } | Select-Object -ExpandProperty IPAddress } $validIps = $allIps | Where-Object { $_ -notlike "169.254.*" } if ($validIps) { $ipAddress = $validIps[0] } else { $apipaIps = $allIps | Where-Object { $_ -like "169.254.*" } if ($apipaIps) { $failStage = "IP_APIPA (DHCP 伺服器無回應,取得無效的 169.254 網段)" } else { $failStage = "IP_Missing (未取得任何 IPv4 位址)" } } # 步驟 2: 檢查閘道器 (Gateway) 是否通 if (-not $failStage) { $gateway = $null if ($activeInterfaceIndex) { $gateway = (Get-NetRoute -DestinationPrefix "0.0.0.0/0" -ErrorAction SilentlyContinue | Where-Object { $_.InterfaceIndex -in $activeInterfaceIndex } | Select-Object -ExpandProperty NextHop | Select-Object -First 1) } if (-not $gateway) { $gateway = (Get-NetRoute -DestinationPrefix "0.0.0.0/0" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty NextHop | Where-Object { $_ -and $_ -ne "0.0.0.0" } | Select-Object -First 1) } if ($gateway) { $pingGw = Test-Connection -ComputerName $gateway -Count 1 -Quiet if (-not $pingGw) { $failStage = "Gateway_Unreachable (有取得 IP 但無法連線至閘道器,實體線路或交換器異常)" } } else { $failStage = "Gateway_NotFound (找不到預設閘道器)" } } # 步驟 3: 檢查外網 IP 是否真不通 (二次確認) if (-not $failStage) { $pingExt = Test-Connection -ComputerName "8.8.8.8" -Count 1 -Quiet if (-not $pingExt) { $failStage = "External_Network_Fail (閘道器通,但無法連線至外網,可能路由器斷線或外線掉線)" } } # 步驟 4: 檢查 DNS 解析是否正常 if (-not $failStage) { try { $resolve = Resolve-DnsName -Name "google.com" -ErrorAction Stop } catch { $failStage = "DNS_Fail (外網可通,但無法解析網域名稱,請檢查 DNS 設定)" } } } # 根據檢測結果設定 PowerShell 視窗背景與字體顏色 if ($isOnline -or -not $failStage) { $host.UI.RawUI.BackgroundColor = "DarkGreen" $host.UI.RawUI.ForegroundColor = "White" } else { $host.UI.RawUI.BackgroundColor = "DarkRed" $host.UI.RawUI.ForegroundColor = "White" } Clear-Host # 渲染美化的輸出畫面 Write-Host "=========================================" -ForegroundColor Cyan Write-Host " 端點網路狀態快速診斷工具 " -ForegroundColor Cyan Write-Host "=========================================" -ForegroundColor Cyan Write-Host "" if ($isOnline) { Write-Host "[*] 快速檢測對外連線 (1.1.1.1)... [ 成功 ]" -ForegroundColor Green } else { Write-Host "[*] 快速檢測對外連線 (1.1.1.1)... [ 失敗 ]" -ForegroundColor Red Write-Host "[!] 開始進行詳細診斷..." -ForegroundColor Yellow Write-Host "" if ($validIps) { Write-Host "[*] 檢查本機 IP 設定... [ 成功 ]" -ForegroundColor Green Write-Host " -> 目前 IP: $ipAddress" } else { Write-Host "[*] 檢查本機 IP 設定... [ 失敗 ]" -ForegroundColor Red } if ($gateway) { Write-Host "[*] 檢查區域網路閘道器 (Gateway)... [ 成功 ] ($gateway)" -ForegroundColor Green } elseif (-not $failStage -or $failStage -like "Gateway*") { Write-Host "[*] 檢查區域網路閘道器 (Gateway)... [ 失敗 ]" -ForegroundColor Red } Write-Host "[*] 檢查外網與 DNS 狀態..." -NoNewline if (-not $failStage) { Write-Host " [ 成功 ]" -ForegroundColor Green } else { Write-Host " [ 失敗 ]" -ForegroundColor Red } } Write-Host "" Write-Host "=========================================" -ForegroundColor Cyan if ($isOnline -or -not $failStage) { Write-Host " 檢測結果:網路完全正常! (OK)" -ForegroundColor Green } else { Write-Host " 檢測結果:網路異常" -ForegroundColor Red Write-Host " 故障點:$failStage" -ForegroundColor Yellow } Write-Host "=========================================" -ForegroundColor Cyan Write-Host "" # 等待按 Enter 鍵 Read-Host "請檢視上方結果,按下 Enter 鍵關閉視窗..." } finally { # 無論如何(包含正常結束、異常、或中斷),離開前一定會將顏色還原回預設值 $host.UI.RawUI.BackgroundColor = $originalBg $host.UI.RawUI.ForegroundColor = $originalFg Clear-Host }