i keep a -DryRun switch on my windows optimizer so i can watch what it would do before it does it. handy when you're editing registry writes and don't want to test them against your own machine.
last week i ran it with -Only "Privacy" -DryRun, just the privacy section, no writes, and for once i actually read the summary box at the bottom instead of skimming past it. the line said:
Fixes Applied: 9 optimizations
the registry was untouched. nothing had been written. i even went and checked a couple of the keys by hand afterward, still in their original state. so that summary was counting nine fixes that never happened.
that's a bad bug for any tool. for a privacy and hardening script it's worse, because the summary is the one thing that tells you what state your machine is in. if a preview says telemetry disabled, advertising id disabled, location tracking disabled, and none of it happened, you close the window thinking you're covered. you're not.
here's how it broke.
the registry helper was already doing the right thing. Set-RegValue checks the dry-run flag, prints a [DRY] line, and returns before writing anything:
if ($script:DryRunMode) {
Write-Dry "Would set $Path\$Name = $Value"
return $true
}
so the actual writes were correctly skipped. the problem was one layer up. each module sets a couple of related keys and then prints one [FIX] line to say "this thing is handled." privacy looked like this:
Set-RegValue "HKLM:\...\DataCollection" "AllowTelemetry" 0
Set-RegValue "HKLM:\...\Policies\DataCollection" "AllowTelemetry" 0
Write-Fix "Telemetry disabled"
and Write-Fix isn't cosmetic. it bumps the counter:
function Write-Fix ([string]$Msg) {
Write-Host " [FIX] $Msg" -ForegroundColor Magenta
Log "[FIX] $Msg"
$script:TotalFixesApplied++
}
so on a dry run, Set-RegValue wrote nothing, printed its [DRY] line, returned. then the module called Write-Fix anyway, which printed [FIX] Telemetry disabled and added one to the total. the privacy pass has nine of those fix lines. every one fired. counter said nine, disk said zero.
the fix is boring, which is usually a good sign. read the flag once at the top of the module, then gate every [FIX] behind it:
$isDry = Get-DryRunMode
Set-RegValue "HKLM:\...\DataCollection" "AllowTelemetry" 0
Set-RegValue "HKLM:\...\Policies\DataCollection" "AllowTelemetry" 0
if (-not $isDry) { Write-Fix "Telemetry disabled" }
the [DRY] Would set ... lines still print, so a dry run still shows you everything it's staging. it just stops taking credit for changes it didn't make. same bug lived in the security module (remote desktop, remote assistance, smbv1, autorun) and the network module (nagle plus the throttling tweak, up to two more phantom fixes). the explorer module had already been doing it right, which is where i copied the pattern from.
then a test so it can't come back:
BeforeEach {
Reset-FixCounter
Set-DryRunMode $true
}
It "Should not increment the fix counter" {
Invoke-PrivacyOptimization -Analysis @{} | Out-Null
Get-FixCount | Should -Be 0
}
It "Should still record what it would do in the report log" {
Invoke-PrivacyOptimization -Analysis @{} | Out-Null
(Get-Report -join "`n") | Should -Match '\[DRY\] Would set .*AllowTelemetry'
}
two things it pins: the counter stays at zero during a dry run, and the [DRY] intent line still lands so a dry run isn't quietly doing nothing at all.
what i don't love about the fix, being honest:
the guard is a convention, not a guarantee. it's an if (-not $isDry) i have to remember to wrap around every new [FIX] line, in every module, forever. nothing stops me adding a fix six months from now and forgetting the wrapper, and the exact bug is back. the counter lives inside Write-Fix, but Write-Fix has no idea dry-run mode exists. the better fix is probably to make Write-Fix itself check the flag and skip the increment, so one function knows the rule instead of a dozen call sites that have to.
second, the test pins "counter is 0," not "every tweak is still staged." if i delete a Set-RegValue by accident, the counter is still 0 and the test still passes. it checks that the dry run doesn't lie about doing work, not that it's still doing the work.
third, even on a real run the counter is soft. it counts fix groups, not registry writes. privacy writes around twenty values across those nine lines, so "9 fixes" was never "9 writes" to start with. making the dry run report 0 is honest. the live number is still more of a vibe than a measurement.
still. a preview that tells you your machine is hardened when it isn't is the kind of small lie that matters more on a security tool than almost anywhere else. worth the boring fix.
repo if you want to pick it apart: https://github.com/TiltedLunar123/Ultimate-Windows-System-Optimizer
Top comments (0)