# ========================================================= # MAX Windows Toolkit - 导出诊断包 # 用途:收集 Windows 故障排查数据并打包为 zip # ========================================================= $Common = "C:\Setup\windows\lib\common.ps1" if (Test-Path $Common) { . $Common } else { function Write-Header { param([string]$Title) Clear-Host; Write-Host "==== $Title ====" -ForegroundColor Green } function Write-OK { Write-Host " OK $($args[0])" -ForegroundColor Green } function Write-Warn { Write-Host " !! $($args[0])" -ForegroundColor Yellow } function Write-Err { Write-Host " XX $($args[0])" -ForegroundColor Red } function Write-Info { Write-Host " $($args[0])" -ForegroundColor White } function Write-Muted { Write-Host " $($args[0])" -ForegroundColor DarkGray } function Pause-Max { Write-Host ""; Read-Host "按 Enter 返回..." } function Write-Line { Write-Host "------------------------------" -ForegroundColor DarkGray } function Write-Section { param([string]$Text) Write-Host ""; Write-Host "-- $Text --" -ForegroundColor Magenta } } Write-Header "导出诊断包" $SetupDir = "C:\Setup" $LogDir = Join-Path $SetupDir "Logs" $DiagRoot = Join-Path $LogDir ("diagnostic-{0}" -f (Get-Date -Format "yyyyMMdd-HHmmss")) New-Item -ItemType Directory -Path $DiagRoot -Force | Out-Null function Write-SectionFile { param( [string]$Name, [scriptblock]$Script ) $Path = Join-Path $DiagRoot $Name try { & $Script | Out-File -FilePath $Path -Encoding UTF8 -Width 240 Write-OK "已导出: $Name" } catch { "ERROR: $($_.Exception.Message)" | Out-File -FilePath $Path -Encoding UTF8 Write-Warn "导出失败: $Name - $($_.Exception.Message)" } } Write-Info "正在收集诊断数据到:" Write-Muted $DiagRoot Write-Line Write-SectionFile "00-summary.txt" { "GeneratedAt=$(Get-Date -Format o)" "ComputerName=$env:COMPUTERNAME" "UserName=$env:USERNAME" "UserDomain=$env:USERDOMAIN" "PowerShell=$($PSVersionTable.PSVersion)" "Is64BitOS=$([Environment]::Is64BitOperatingSystem)" } Write-SectionFile "01-systeminfo.txt" { systeminfo } Write-SectionFile "02-computer-info.txt" { Get-ComputerInfo | Format-List * } Write-SectionFile "03-ipconfig.txt" { ipconfig /all } Write-SectionFile "04-route.txt" { route print } Write-SectionFile "05-dns-client.txt" { Get-DnsClientServerAddress | Format-Table -AutoSize } Write-SectionFile "06-proxy.txt" { "WinHTTP 代理:" netsh winhttp show proxy "" "Internet 设置代理:" Get-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" | Select-Object ProxyEnable, ProxyServer, AutoConfigURL | Format-List } Write-SectionFile "07-network-test.txt" { foreach ($Target in @("dl.unvmax.com", "kms.unvmax.com", "www.microsoft.com", "www.baidu.com")) { "===== $Target =====" Test-NetConnection $Target -Port 443 -WarningAction SilentlyContinue | Format-List } "===== kms.unvmax.com:1688 =====" Test-NetConnection kms.unvmax.com -Port 1688 -WarningAction SilentlyContinue | Format-List } Write-SectionFile "08-services.txt" { Get-Service | Sort-Object Status, Name | Format-Table -AutoSize } Write-SectionFile "09-processes.txt" { Get-Process | Sort-Object CPU -Descending | Select-Object -First 80 | Format-Table -AutoSize } Write-SectionFile "10-disks.txt" { Get-PSDrive -PSProvider FileSystem | Format-Table -AutoSize; Get-Volume | Format-Table -AutoSize } Write-SectionFile "11-hotfix.txt" { Get-HotFix | Sort-Object InstalledOn -Descending | Format-Table -AutoSize } Write-SectionFile "12-installed-programs.txt" { $Paths = @( "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*", "HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*", "HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*" ) Get-ItemProperty $Paths -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName } | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate | Sort-Object DisplayName | Format-Table -AutoSize } Write-SectionFile "13-winget-list.txt" { if (Get-Command winget -ErrorAction SilentlyContinue) { winget list --accept-source-agreements } else { "winget 未找到" } } Write-SectionFile "14-event-errors-system.txt" { Get-WinEvent -FilterHashtable @{LogName='System'; Level=1,2; StartTime=(Get-Date).AddDays(-7)} -MaxEvents 120 | Format-List TimeCreated, ProviderName, Id, LevelDisplayName, Message } Write-SectionFile "15-event-errors-application.txt" { Get-WinEvent -FilterHashtable @{LogName='Application'; Level=1,2; StartTime=(Get-Date).AddDays(-7)} -MaxEvents 120 | Format-List TimeCreated, ProviderName, Id, LevelDisplayName, Message } Write-SectionFile "16-firewall.txt" { Get-NetFirewallProfile | Format-List * } Write-SectionFile "17-listening-ports.txt" { Get-NetTCPConnection -State Listen | Sort-Object LocalPort | Format-Table -AutoSize } Write-SectionFile "18-scheduled-tasks.txt" { Get-ScheduledTask | Select-Object TaskPath, TaskName, State | Sort-Object TaskPath, TaskName | Format-Table -AutoSize } Write-SectionFile "19-setup-logs.txt" { if (Test-Path $LogDir) { Get-ChildItem $LogDir -File -ErrorAction SilentlyContinue | Sort-Object LastWriteTime -Descending | Select-Object Name, Length, LastWriteTime | Format-Table -AutoSize } else { "无 C:\Setup\Logs 目录" } } Write-SectionFile "20-rustdesk.txt" { $Candidates = @("C:\Program Files\RustDesk\rustdesk.exe", "C:\Program Files (x86)\RustDesk\rustdesk.exe") foreach ($Candidate in $Candidates) { if (Test-Path $Candidate) { "RustDeskExe=$Candidate" } } Get-Process -Name rustdesk -ErrorAction SilentlyContinue | Format-Table -AutoSize } # 复制最近的工具包日志,排除诊断文件夹本身 try { $LogCopy = Join-Path $DiagRoot "setup-logs-copy" New-Item -ItemType Directory -Path $LogCopy -Force | Out-Null Get-ChildItem $LogDir -File -ErrorAction SilentlyContinue | Where-Object { $_.Length -lt 20MB } | Sort-Object LastWriteTime -Descending | Select-Object -First 30 | Copy-Item -Destination $LogCopy -Force -ErrorAction SilentlyContinue } catch {} $ZipPath = "$DiagRoot.zip" try { if (Test-Path $ZipPath) { Remove-Item $ZipPath -Force } Compress-Archive -Path (Join-Path $DiagRoot "*") -DestinationPath $ZipPath -Force Write-Line Write-OK "诊断包已创建:" Write-Info $ZipPath Write-Info "可将此 zip 文件发送以供远程故障排查" } catch { Write-Err "创建 zip 包失败" Write-Muted $_.Exception.Message } Pause-Max