Skip to content

Commit 2bdec08

Browse files
committed
v1.9.26 — Fix 9 bugs: disk cleanup byte counter, NTP exit codes, menu navigation, firewall state, CSV null partition, IP display, iSCSI NIC wrapping
1 parent 8d20d42 commit 2bdec08

12 files changed

Lines changed: 81 additions & 24 deletions

Changelog.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# Changelog
22

3+
## v1.9.26
4+
5+
- **Bug Fix:** Disk cleanup byte counter was corrupted by directory entries — `Get-ChildItem` without `-File` included directories, whose `.Length` returns name character count (not byte size). The "freed space" report was inflated with nonsense values. Added `-File` flag to both temp cleanup loops (20-DiskCleanup).
6+
- **Bug Fix:** NTP configuration reported "configured successfully" even when `w32tm /config` or `/resync` failed — native executables set `$LASTEXITCODE` but don't throw PowerShell exceptions, so the `try/catch` caught nothing. Now checks `$LASTEXITCODE` after each `w32tm` call (19-NTPConfiguration).
7+
- **Bug Fix:** Detailed time status display truncation logic was broken for `w32tm` error output — `2>&1` redirects stderr as `ErrorRecord` objects, not strings. Accessing `.Length` on `ErrorRecord` returns `$null`, making the `Substring` guard a no-op. Now converts to string first (19-NTPConfiguration).
8+
- **Bug Fix:** Navigation commands (`exit`, `help`, `back`, `b`/`B`) were silently ignored in two network menus — `Start-Show-HostNetworkIPMenu` and `Start-Show-VM-NetworkMenu` were missing the `Test-NavigationCommand` call that all other menu runners have. Typing "exit" fell into the "Invalid choice" handler (49-MenuRunner).
9+
- **Bug Fix:** Firewall state detection compared `.Enabled` (a `GpoBoolean` enum) to the string `"True"` instead of `$true` — worked by accident via type coercion but reported "Disabled" instead of using the catch-block "Unknown" when a profile was null (05-SystemCheck).
10+
- **Bug Fix:** Current IP display garbled output when adapter had multiple IPv4 addresses — `Get-NetIPAddress` can return multiple objects, causing `$currentIP.IPAddress` to concatenate array elements. Added `Select-Object -First 1` (07-IPConfiguration).
11+
- **Bug Fix:** Cluster dashboard and CSV health checks crashed or showed 0 GB for faulted/offline CSVs — `SharedVolumeInfo.Partition` is null when a CSV is unavailable, causing `$null / 1GB` to produce zeros. Added null guards with skip+warning in all three CSV iteration loops (51-ClusterDashboard).
12+
- **Bug Fix:** iSCSI NIC identification menu couldn't select adapters when only one physical NIC existed — pipeline result wasn't wrapped in `@()`, so `.Count` and array indexing failed on single objects. Wrapped all three `Get-NetAdapter` assignments (10-iSCSI).
13+
- 63 modules, 1854 tests
14+
315
## v1.9.25
416

517
- **Bug Fix:** All bare `Exit` statements caused a "System error" dialog when running as the compiled EXE — ps2exe wraps `Exit` in a way that throws `BreakException`. Replaced with `[Environment]::Exit()` in both `Exit-Script` exit paths (47-ExitCleanup) and batch mode entry/exit (50-EntryPoint). Affects 4 code paths: normal exit, no-reboot exit, batch admin check failure, and batch completion.

Header.ps1

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,22 @@
3030
7h3 4b1d3r
3131
3232
.VERSION
33-
1.9.25
33+
1.9.26
3434
3535
.LAST UPDATED
3636
02/25/2026
3737
38+
.CHANGELOG v1.9.26
39+
BUG FIXES:
40+
- FIXED: Disk cleanup byte counter included directory name lengths instead of file sizes — Get-ChildItem without -File counted DirectoryInfo.Length (name char count) as freed bytes (20-DiskCleanup)
41+
- FIXED: NTP configuration reported success even when w32tm failed — native exe exit codes were piped to Out-Null and never checked (19-NTPConfiguration)
42+
- FIXED: Detailed time status display broke on w32tm error output — ErrorRecord objects from 2>&1 lack .Length property, causing truncation logic to silently fail (19-NTPConfiguration)
43+
- FIXED: Navigation commands (exit, help, back) ignored in Host IP Network and VM Network menus — missing Test-NavigationCommand call before switch statement (49-MenuRunner)
44+
- FIXED: Firewall state check compared .Enabled to string "True" instead of boolean $true — also added null guard for missing firewall profiles (05-SystemCheck)
45+
- FIXED: Current IP display garbled when adapter had multiple IPv4 addresses — Get-NetIPAddress can return multiple objects (07-IPConfiguration)
46+
- FIXED: Cluster dashboard crashed on faulted/offline CSVs — SharedVolumeInfo.Partition is null when CSV is unavailable, causing division on null (51-ClusterDashboard)
47+
- FIXED: NIC identification menu failed with single physical adapter — pipeline result not wrapped in @() for reliable .Count and array indexing (10-iSCSI)
48+
3849
.CHANGELOG v1.9.25
3950
BUG FIXES:
4051
- FIXED: Bare Exit statements caused "System error" dialog when running as compiled EXE — ps2exe requires [Environment]::Exit() instead of Exit (47-ExitCleanup, 50-EntryPoint)

Modules/00-Initialization.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ if (-not $script:ModuleRoot) { $script:ModuleRoot = $PSScriptRoot }
135135
if (-not $script:ModuleRoot -and $script:ScriptPath) {
136136
$script:ModuleRoot = [System.IO.Path]::GetDirectoryName($script:ScriptPath)
137137
}
138-
$script:ScriptVersion = "1.9.25"
138+
$script:ScriptVersion = "1.9.26"
139139
$script:ScriptStartTime = Get-Date
140140

141141
# OS version detection (for feature compatibility)

Modules/05-SystemCheck.ps1

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,9 @@ function Get-FirewallState {
161161
$publicProfile = Get-NetFirewallProfile -Profile Public -ErrorAction SilentlyContinue
162162

163163
return @{
164-
Domain = if ($domainProfile.Enabled -eq "True") { "Enabled" } else { "Disabled" }
165-
Private = if ($privateProfile.Enabled -eq "True") { "Enabled" } else { "Disabled" }
166-
Public = if ($publicProfile.Enabled -eq "True") { "Enabled" } else { "Disabled" }
164+
Domain = if ($null -ne $domainProfile -and $domainProfile.Enabled -eq $true) { "Enabled" } else { "Disabled" }
165+
Private = if ($null -ne $privateProfile -and $privateProfile.Enabled -eq $true) { "Enabled" } else { "Disabled" }
166+
Public = if ($null -ne $publicProfile -and $publicProfile.Enabled -eq $true) { "Enabled" } else { "Disabled" }
167167
}
168168
}
169169
catch {

Modules/07-IPConfiguration.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ function Set-VMIPAddress {
133133
)
134134

135135
# Get current IP configuration
136-
$currentIP = Get-NetIPAddress -InterfaceAlias $selectedAdapterName -AddressFamily IPv4 -ErrorAction SilentlyContinue
136+
$currentIP = Get-NetIPAddress -InterfaceAlias $selectedAdapterName -AddressFamily IPv4 -ErrorAction SilentlyContinue | Select-Object -First 1
137137
if ($currentIP) {
138138
Write-OutputColor "Current IP: $($currentIP.IPAddress)/$($currentIP.PrefixLength)" -color "Info"
139139
}

Modules/10-iSCSI.ps1

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,13 +1228,13 @@ function Start-Show-iSCSISANMenu {
12281228
}
12291229
"2" {
12301230
# NIC identification helper
1231-
$adapters = Get-NetAdapter | Where-Object {
1231+
$adapters = @(Get-NetAdapter | Where-Object {
12321232
$_.Name -notlike "vEthernet*" -and
12331233
$_.InterfaceDescription -notlike "*Hyper-V*" -and
12341234
$_.InterfaceDescription -notlike "*Virtual*"
1235-
}
1235+
})
12361236

1237-
if (-not $adapters -or $adapters.Count -eq 0) {
1237+
if ($adapters.Count -eq 0) {
12381238
Write-OutputColor " No physical adapters found." -color "Error"
12391239
Write-PressEnter
12401240
}
@@ -1246,23 +1246,23 @@ function Start-Show-iSCSISANMenu {
12461246
}
12471247
elseif ($identifyChoice -match '^[Rr]$') {
12481248
# Refresh adapter list
1249-
$adapters = Get-NetAdapter | Where-Object {
1249+
$adapters = @(Get-NetAdapter | Where-Object {
12501250
$_.Name -notlike "vEthernet*" -and
12511251
$_.InterfaceDescription -notlike "*Hyper-V*" -and
12521252
$_.InterfaceDescription -notlike "*Virtual*"
1253-
}
1253+
})
12541254
continue
12551255
}
12561256
elseif ($identifyChoice -match '^\d+$') {
12571257
$idx = [int]$identifyChoice
12581258
if ($idx -ge 1 -and $idx -le $adapters.Count) {
12591259
Disable-NICForIdentification -Adapter $adapters[$idx - 1]
12601260
# Refresh after enable
1261-
$adapters = Get-NetAdapter | Where-Object {
1261+
$adapters = @(Get-NetAdapter | Where-Object {
12621262
$_.Name -notlike "vEthernet*" -and
12631263
$_.InterfaceDescription -notlike "*Hyper-V*" -and
12641264
$_.InterfaceDescription -notlike "*Virtual*"
1265-
}
1265+
})
12661266
}
12671267
}
12681268
}

Modules/19-NTPConfiguration.ps1

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,18 +109,26 @@ function Set-NTPServer {
109109
try {
110110
if ($IsDomainType) {
111111
# Configure to sync with domain hierarchy
112-
w32tm /config /syncfromflags:DOMHIER /update | Out-Null
112+
$null = w32tm /config /syncfromflags:DOMHIER /update 2>&1
113113
} else {
114114
# Configure manual NTP server
115-
w32tm /config /manualpeerlist:$Server /syncfromflags:manual /reliable:yes /update | Out-Null
115+
$null = w32tm /config /manualpeerlist:$Server /syncfromflags:manual /reliable:yes /update 2>&1
116+
}
117+
118+
if ($LASTEXITCODE -ne 0) {
119+
Write-OutputColor " Failed to configure NTP server (exit code $LASTEXITCODE)." -color "Error"
120+
return
116121
}
117122

118123
# Restart time service
119124
Restart-Service w32time -Force -ErrorAction SilentlyContinue
120125
Start-Sleep -Seconds 2
121126

122127
# Force sync
123-
w32tm /resync /force | Out-Null
128+
$null = w32tm /resync /force 2>&1
129+
if ($LASTEXITCODE -ne 0) {
130+
Write-OutputColor " NTP configured but time sync failed (exit code $LASTEXITCODE)." -color "Warning"
131+
}
124132

125133
Write-OutputColor " NTP server configured successfully." -color "Success"
126134
Add-SessionChange -Category "System" -Description "Configured NTP server: $Server"
@@ -139,8 +147,9 @@ function Show-DetailedTimeStatus {
139147

140148
$status = w32tm /query /status 2>&1
141149
foreach ($line in $status) {
142-
if ($line -and $line.ToString().Trim()) {
143-
$displayLine = if ($line.Length -gt 68) { $line.Substring(0,65) + "..." } else { $line }
150+
$lineStr = $line.ToString()
151+
if ($lineStr.Trim()) {
152+
$displayLine = if ($lineStr.Length -gt 68) { $lineStr.Substring(0,65) + "..." } else { $lineStr }
144153
Write-OutputColor "$(" $displayLine".PadRight(72))" -color "Info"
145154
}
146155
}

Modules/20-DiskCleanup.ps1

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,20 +98,20 @@ function Invoke-QuickClean {
9898

9999
# User temp
100100
if (Test-Path $env:TEMP) {
101-
$files = Get-ChildItem $env:TEMP -Recurse -Force -ErrorAction SilentlyContinue
101+
$files = Get-ChildItem $env:TEMP -Recurse -Force -File -ErrorAction SilentlyContinue
102102
foreach ($file in $files) {
103103
$fileSize = $file.Length
104-
Remove-Item $file.FullName -Force -Recurse -ErrorAction SilentlyContinue
104+
Remove-Item $file.FullName -Force -ErrorAction SilentlyContinue
105105
if (-not (Test-Path $file.FullName)) { $cleaned += $fileSize }
106106
}
107107
}
108108

109109
# Windows temp
110110
if (Test-Path "C:\Windows\Temp") {
111-
$files = Get-ChildItem "C:\Windows\Temp" -Recurse -Force -ErrorAction SilentlyContinue
111+
$files = Get-ChildItem "C:\Windows\Temp" -Recurse -Force -File -ErrorAction SilentlyContinue
112112
foreach ($file in $files) {
113113
$fileSize = $file.Length
114-
Remove-Item $file.FullName -Force -Recurse -ErrorAction SilentlyContinue
114+
Remove-Item $file.FullName -Force -ErrorAction SilentlyContinue
115115
if (-not (Test-Path $file.FullName)) { $cleaned += $fileSize }
116116
}
117117
}

Modules/49-MenuRunner.ps1

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,10 @@ function Start-Show-HostNetworkIPMenu {
491491
while ($true) {
492492
$vmNetworkChoice = Show-Host-IPNetworkMenu -selectedAdapterName $selectedAdapterName
493493

494+
$navResult = Test-NavigationCommand -UserInput $vmNetworkChoice
495+
if ($navResult.Action -eq "exit") { Exit-Script; return }
496+
if ($navResult.Action -eq "back") { return }
497+
494498
switch ($vmNetworkChoice) {
495499
"1" {
496500
Set-VMIPAddress -selectedAdapterName $selectedAdapterName
@@ -538,6 +542,10 @@ function Start-Show-VM-NetworkMenu {
538542
while ($true) {
539543
$vmNetworkChoice = Show-VM-NetworkMenu -selectedAdapterName $selectedAdapterName
540544

545+
$navResult = Test-NavigationCommand -UserInput $vmNetworkChoice
546+
if ($navResult.Action -eq "exit") { Exit-Script; return }
547+
if ($navResult.Action -eq "back") { return }
548+
541549
switch ($vmNetworkChoice) {
542550
"1" {
543551
Set-VMIPAddress -selectedAdapterName $selectedAdapterName

Modules/51-ClusterDashboard.ps1

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ function Show-ClusterDashboard {
6363

6464
foreach ($csv in $csvs) {
6565
$partition = $csv.SharedVolumeInfo.Partition
66+
if (-not $partition) {
67+
Write-OutputColor "$(" $($csv.Name) - Partition info unavailable".PadRight(72))" -color "Warning"
68+
continue
69+
}
6670

6771
$totalGB = [math]::Round($partition.Size / 1GB, 0)
6872
$freeGB = [math]::Round($partition.FreeSpace / 1GB, 0)
@@ -285,6 +289,12 @@ function Show-CSVHealth {
285289
foreach ($csv in $csvs) {
286290
$partition = $csv.SharedVolumeInfo.Partition
287291
$redirected = $csv.SharedVolumeInfo.FaultState
292+
if (-not $partition) {
293+
Write-OutputColor " ┌────────────────────────────────────────────────────────────────────────┐" -color "Warning"
294+
Write-OutputColor "$(" $($csv.Name) - Partition info unavailable".PadRight(72))" -color "Warning"
295+
Write-OutputColor " └────────────────────────────────────────────────────────────────────────┘" -color "Warning"
296+
continue
297+
}
288298

289299
$totalGB = [math]::Round($partition.Size / 1GB, 1)
290300
$freeGB = [math]::Round($partition.FreeSpace / 1GB, 1)
@@ -487,6 +497,13 @@ function Initialize-ClusterCSV {
487497
$issues = 0
488498
foreach ($csv in $csvs) {
489499
$partition = $csv.SharedVolumeInfo.Partition
500+
if (-not $partition) {
501+
Write-OutputColor " ┌────────────────────────────────────────────────────────────────────────┐" -color "Warning"
502+
Write-OutputColor "$(" $($csv.Name) - Partition info unavailable".PadRight(72))" -color "Warning"
503+
Write-OutputColor " └────────────────────────────────────────────────────────────────────────┘" -color "Warning"
504+
$issues++
505+
continue
506+
}
490507
$totalGB = [math]::Round($partition.Size / 1GB, 0)
491508
$freeGB = [math]::Round($partition.FreeSpace / 1GB, 0)
492509
$usedPct = if ($totalGB -gt 0) { [math]::Round(($totalGB - $freeGB) / $totalGB * 100, 0) } else { 0 }

0 commit comments

Comments
 (0)