1- # Portable Sysinternals System Tester - FINAL MERGED VERSION
1+ # Portable Sysinternals System Tester
22# Created by Pacific Northwest Computers - 2025
3- # Complete Production Version - v2.2 (Merged and Debugged)
3+ # Complete Production Version - v2.2
44
55param ([switch ]$AutoRun )
66
77# Constants
88$script :VERSION = " 2.2"
9- $script :DXDIAG_TIMEOUT = 50
10- $script :ENERGY_DURATION = 20
11- $script :CPU_TEST_SECONDS = 30
9+ $script :DXDIAG_TIMEOUT = 45
10+ $script :ENERGY_DURATION = 15
11+ $script :CPU_TEST_SECONDS = 10
1212$script :MAX_PATH_LENGTH = 240
1313$script :MIN_TOOL_SIZE_KB = 50
14- $script :DNS_TEST_TARGETS = @ (" google.com" , " microsoft.com" , " cloudflare.com" , " github.com" ) # Added DNS Targets
1514
1615# Paths
17- # Uses the more robust method for getting the script root regardless of launch method
1816$ScriptRoot = if ($PSScriptRoot ) { $PSScriptRoot } else { Split-Path - Parent $MyInvocation.MyCommand.Path }
1917$DriveLetter = (Split-Path - Qualifier $ScriptRoot ).TrimEnd(' \' )
2018$SysinternalsPath = Join-Path $ScriptRoot " Sysinternals"
@@ -31,7 +29,6 @@ Write-Host "Running from: $DriveLetter" -ForegroundColor Cyan
3129
3230# Detect if launched via batch file
3331function Test-LauncherAwareness {
34- # ... (code unchanged)
3532 try {
3633 $parentPID = (Get-Process - Id $PID ).Parent.Id
3734 if ($parentPID ) {
@@ -49,7 +46,6 @@ function Test-LauncherAwareness {
4946
5047# Check admin privileges
5148function Test-AdminPrivileges {
52- # ... (code unchanged)
5349 try {
5450 $identity = [Security.Principal.WindowsIdentity ]::GetCurrent()
5551 $principal = New-Object Security.Principal.WindowsPrincipal($identity )
@@ -67,12 +63,22 @@ function Test-AdminPrivileges {
6763
6864# Tool integrity verification
6965function Test-ToolIntegrity {
70- # ... (code unchanged)
7166 param ([string ]$ToolName )
7267
7368 $toolPath = Join-Path $SysinternalsPath " $ToolName .exe"
7469
75- # ... (rest of function logic)
70+ # Check if file exists
71+ if (! (Test-Path $toolPath )) {
72+ return @ {Status = " MISSING" ; Details = " File not found" }
73+ }
74+
75+ # Check file size
76+ $fileInfo = Get-Item $toolPath
77+ if ($fileInfo.Length -lt ($script :MIN_TOOL_SIZE_KB * 1 KB )) {
78+ return @ {Status = " BAD_SIZE" ; Details = " File too small: $ ( $fileInfo.Length ) bytes" }
79+ }
80+
81+ # Check digital signature
7682 try {
7783 $signature = Get-AuthenticodeSignature $toolPath - ErrorAction Stop
7884
@@ -93,6 +99,104 @@ function Test-ToolIntegrity {
9399 }
94100}
95101
102+ # Verify all tools
103+ function Test-ToolVerification {
104+ Write-Host " `n ========================================" - ForegroundColor Cyan
105+ Write-Host " TOOL INTEGRITY VERIFICATION" - ForegroundColor Cyan
106+ Write-Host " ========================================" - ForegroundColor Cyan
107+ Write-Host " "
108+
109+ $allTools = @ (
110+ " psinfo" , " coreinfo" , " pslist" , " handle" , " clockres" ,
111+ " autorunsc" , " du" , " streams" , " contig" , " sigcheck" ,
112+ " testlimit" , " diskext" , " listdlls"
113+ )
114+
115+ $stats = @ {
116+ VALID_MS = 0 ; VALID_OTHER = 0 ; NOT_SIGNED = 0
117+ BAD_SIZE = 0 ; BAD_SIGNATURE = 0 ; MISSING = 0 ; CHECK_FAILED = 0
118+ }
119+
120+ foreach ($tool in $allTools ) {
121+ $result = Test-ToolIntegrity - ToolName $tool
122+ $stats [$result.Status ]++
123+
124+ $color = switch ($result.Status ) {
125+ " VALID_MS" { " Green" }
126+ " VALID_OTHER" { " Cyan" }
127+ " NOT_SIGNED" { " Yellow" }
128+ " MISSING" { " Red" }
129+ " BAD_SIZE" { " Red" }
130+ " BAD_SIGNATURE" { " Red" }
131+ " CHECK_FAILED" { " Yellow" }
132+ }
133+
134+ $statusText = switch ($result.Status ) {
135+ " VALID_MS" { " [OK-MS]" }
136+ " VALID_OTHER" { " [OK-OTHER]" }
137+ " NOT_SIGNED" { " [NO-SIG]" }
138+ " MISSING" { " [MISSING]" }
139+ " BAD_SIZE" { " [BAD-SIZE]" }
140+ " BAD_SIGNATURE" { " [BAD-SIG]" }
141+ " CHECK_FAILED" { " [ERROR]" }
142+ }
143+
144+ Write-Host " $statusText $tool " - ForegroundColor $color
145+ if ($result.Details -and $result.Status -ne " VALID_MS" ) {
146+ Write-Host " $ ( $result.Details ) " - ForegroundColor DarkGray
147+ }
148+ }
149+
150+ Write-Host " "
151+ Write-Host " ========================================" - ForegroundColor Cyan
152+ Write-Host " SUMMARY:" - ForegroundColor White
153+ Write-Host " Valid (Microsoft): $ ( $stats.VALID_MS ) " - ForegroundColor Green
154+ Write-Host " Valid (Other): $ ( $stats.VALID_OTHER ) " - ForegroundColor Cyan
155+ Write-Host " Not Signed: $ ( $stats.NOT_SIGNED ) " - ForegroundColor Yellow
156+ Write-Host " Bad Size: $ ( $stats.BAD_SIZE ) " - ForegroundColor Red
157+ Write-Host " Bad Signature: $ ( $stats.BAD_SIGNATURE ) " - ForegroundColor Red
158+ Write-Host " Missing: $ ( $stats.MISSING ) " - ForegroundColor Red
159+ Write-Host " Check Failed: $ ( $stats.CHECK_FAILED ) " - ForegroundColor Yellow
160+ Write-Host " "
161+
162+ $totalIssues = $stats.BAD_SIZE + $stats.BAD_SIGNATURE + $stats.MISSING + $stats.CHECK_FAILED
163+ if ($totalIssues -eq 0 -and $stats.VALID_MS -gt 0 ) {
164+ Write-Host " STATUS: All present tools are verified and safe to use" - ForegroundColor Green
165+ } elseif ($totalIssues -gt 0 ) {
166+ Write-Host " STATUS: $totalIssues issue(s) detected - recommend re-download" - ForegroundColor Yellow
167+ if ($script :LaunchedViaBatch ) {
168+ Write-Host " ACTION: Use Batch Menu Option 5 to re-download tools" - ForegroundColor Yellow
169+ }
170+ }
171+ Write-Host " "
172+ }
173+
174+ # Initialize environment
175+ function Initialize-Environment {
176+ Write-Host " Initializing..." - ForegroundColor Yellow
177+
178+ Test-LauncherAwareness | Out-Null
179+ Test-AdminPrivileges | Out-Null
180+
181+ # Path length check
182+ if ($ScriptRoot.Length -gt $script :MAX_PATH_LENGTH ) {
183+ Write-Host " WARNING: Path length is $ ( $ScriptRoot.Length ) chars" - ForegroundColor Yellow
184+ Write-Host " Consider moving to shorter path (Windows limit: 260)" - ForegroundColor Yellow
185+ }
186+
187+ # Check tools folder
188+ if (! (Test-Path $SysinternalsPath )) {
189+ Write-Host " ERROR: Sysinternals folder not found!" - ForegroundColor Red
190+ Write-Host " Expected: $SysinternalsPath " - ForegroundColor Yellow
191+ if ($script :LaunchedViaBatch ) {
192+ Write-Host " ACTION: Use Batch Menu Option 5 to download tools automatically" - ForegroundColor Yellow
193+ } else {
194+ Write-Host " ACTION: Download from https://download.sysinternals.com/files/SysinternalsSuite.zip" - ForegroundColor Yellow
195+ Write-Host " Extract to: $SysinternalsPath " - ForegroundColor Yellow
196+ }
197+ return $false
198+ }
199+
96200 # Check for key tools
97201 $tools = @ (" psinfo.exe" , " coreinfo.exe" , " pslist.exe" , " handle.exe" , " clockres.exe" )
98202 $found = 0
@@ -163,7 +267,7 @@ function Clean-ToolOutput {
163267 return ($cleaned | Select-Object - First 40 ) -join " `n "
164268}
165269
166- # Run tool (Uses v2.2 reliable call & quotes path for spaces)
270+ # Run tool
167271function Run-Tool {
168272 param (
169273 [string ]$ToolName ,
@@ -190,20 +294,13 @@ function Run-Tool {
190294 Write-Host " Running $ToolName ..." - ForegroundColor Cyan
191295 try {
192296 $start = Get-Date
193-
194- # Add -accepteula for necessary tools (from v2.2 logic)
195- if ($ToolName -in @ (" psinfo" , " pslist" , " handle" , " autorunsc" , " testlimit" , " contig" , " coreinfo" , " streams" , " sigcheck" )) {
297+ if ($ToolName -in @ (" psinfo" , " pslist" , " handle" , " autorunsc" , " testlimit" , " contig" )) {
196298 $Args = " -accepteula $Args "
197299 }
198300
199- # ARG FIX: This ensures the path is quoted to handle spaces (like in C:\Users\Jon Pienkowski)
200301 $argArray = if ($Args.Trim ()) { $Args.Split (' ' ) | Where-Object { $_ } } else { @ () }
201-
202- # *** CRITICAL FIX: Quote the executable path ***
203- $rawOutput = & " $toolPath " $argArray 2>&1 | Out-String
204-
302+ $rawOutput = & $toolPath $argArray 2>&1 | Out-String
205303 $duration = ((Get-Date ) - $start ).TotalMilliseconds
206-
207304 $cleanOutput = Clean - ToolOutput - ToolName $ToolName - RawOutput $rawOutput
208305
209306 $script :TestResults += @ {
@@ -220,17 +317,13 @@ function Run-Tool {
220317 Write-Host " ERROR: $ToolName - $ ( $_.Exception.Message ) " - ForegroundColor Red
221318 }
222319}
223- # ----------------------------------------------------
224- # END UTILITY FUNCTIONS
225- # ----------------------------------------------------
226320
227321# Test: System Info
228322function Test-SystemInfo {
229323 Write-Host " `n === System Information ===" - ForegroundColor Green
230324 Run- Tool - ToolName " psinfo" - Args " -h -s -d" - Description " System information"
231325 Run- Tool - ToolName " clockres" - Description " Clock resolution"
232326
233- # Get WMI info and store in System-Overview
234327 try {
235328 $os = Get-CimInstance Win32_OperatingSystem - ErrorAction Stop
236329 $cs = Get-CimInstance Win32_ComputerSystem - ErrorAction Stop
@@ -257,7 +350,6 @@ function Test-CPU {
257350 Write-Host " `n === CPU Testing ===" - ForegroundColor Green
258351 Run- Tool - ToolName " coreinfo" - Args " -v -f -c" - Description " CPU architecture"
259352
260- # Get WMI CPU details
261353 try {
262354 $cpu = Get-CimInstance Win32_Processor - ErrorAction Stop | Select-Object - First 1
263355 $info = @"
@@ -277,11 +369,6 @@ L3 Cache: $($cpu.L3CacheSize) KB
277369 Write-Host " Error getting CPU details" - ForegroundColor Yellow
278370 }
279371
280- # Run remaining CPU-related tools
281- Run- Tool - ToolName " pslist" - Args " -t" - Description " Process tree snapshot"
282- Run- Tool - ToolName " handle" - Args " -p explorer" - Description " Explorer handles"
283-
284- # CPU stress test
285372 Write-Host " Running CPU test ($script :CPU_TEST_SECONDS sec - synthetic)..." - ForegroundColor Yellow
286373 try {
287374 $start = Get-Date
@@ -462,17 +549,6 @@ function Test-StorageSMART {
462549
463550 if (-not $lines ) { $lines = @ (" SMART data not available (driver limitation)" ) }
464551
465- Write-Host " Running DISM and SFC (may take 5-15 min)..." - ForegroundColor Yellow
466- try {
467- $start = Get-Date
468- # DISM
469- Write-Host " Running DISM..." - ForegroundColor Yellow
470- $dismResult = DISM / Online / Cleanup- Image / CheckHealth 2>&1 | Out-String
471- # SFC
472- Write-Host " Running SFC..." - ForegroundColor Yellow
473- $sfcResult = sfc / scannow 2>&1 | Out-String
474- $duration = ((Get-Date ) - $start ).TotalMilliseconds
475-
476552 $script :TestResults += @ {
477553 Tool = " Storage-SMART" ; Description = " SMART data"
478554 Status = " SUCCESS" ; Output = ($lines -join " `n " ); Duration = 100
@@ -502,7 +578,7 @@ function Test-Trim {
502578 Tool = " SSD-TRIM" ; Description = " TRIM status"
503579 Status = " SUCCESS" ; Output = ($txt -join " `n " ); Duration = 50
504580 }
505- Write-Host " SMART data collected" - ForegroundColor Green
581+ Write-Host " TRIM status collected" - ForegroundColor Green
506582 } catch {
507583 Write-Host " TRIM check failed" - ForegroundColor Yellow
508584 }
@@ -662,7 +738,7 @@ function Test-GPU {
662738 Start-Sleep - Milliseconds 500
663739 $elapsed += 0.5
664740 }
665-
741+
666742 if (Test-Path $dx ) {
667743 Start-Sleep - Seconds 1
668744 $raw = Get-Content $dx - Raw - ErrorAction Stop
@@ -1120,11 +1196,6 @@ function Generate-Report {
11201196 $recommendations += " • GOOD: Low memory usage ($usage %) - plenty of RAM available"
11211197 }
11221198 }
1123-
1124- # --- 5. RECOMMENDATIONS ENGINE ---
1125- $cleanReport += " "
1126- $cleanReport += " RECOMMENDATIONS:"
1127- $cleanReport += " ----------------"
11281199
11291200 # === STORAGE HEALTH ===
11301201 $smartInfo = $TestResults | Where-Object {$_.Tool -eq " Storage-SMART" }
@@ -1417,7 +1488,7 @@ function Show-Menu {
14171488 Write-Host " 18. Clear Results" - ForegroundColor Red
14181489 Write-Host " Q. Quit"
14191490 Write-Host " "
1420- Write-Host " Tests completed: $ ( $script : TestResults.Count ) " - ForegroundColor Gray
1491+ Write-Host " Tests completed: $ ( $TestResults.Count ) " - ForegroundColor Gray
14211492}
14221493
14231494function Start-Menu {
0 commit comments