param([ValidateSet('install','audit','uninstall')][string]$Action = 'audit') $ErrorActionPreference = 'Stop' $stateDir = Join-Path $env:ProgramData 'Comitari\HardeningSafe' $stateFile = Join-Path $stateDir 'original-values.json' # Only low-impact, machine-wide controls. Deliberately excludes Windows LAPS, accounts, # services, remote management, networking, firewall policy, BitLocker and Defender. $settings = @( @{ Path='HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer'; Name='NoAutorun'; Value=1 }, @{ Path='HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer'; Name='NoDriveTypeAutoRun'; Value=255 }, @{ Path='HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer'; Name='NoAutoplayfornonVolume'; Value=1 }, @{ Path='HKLM:\SOFTWARE\Policies\Microsoft\Windows\Personalization'; Name='NoLockScreenCamera'; Value=1 }, @{ Path='HKLM:\SOFTWARE\Policies\Microsoft\Windows\Personalization'; Name='NoLockScreenSlideshow'; Value=1 } ) function Read-Value($path, $name) { if (-not (Test-Path -LiteralPath $path)) { return @{ Exists=$false; Value=$null } } $key = Get-Item -LiteralPath $path if ($key.GetValueNames() -contains $name) { return @{ Exists=$true; Value=[int]$key.GetValue($name) } } return @{ Exists=$false; Value=$null } } function Write-Value($path, $name, [int]$value) { if (-not (Test-Path -LiteralPath $path)) { New-Item -Path $path -Force | Out-Null } New-ItemProperty -LiteralPath $path -Name $name -Value $value -PropertyType DWord -Force | Out-Null } if ($Action -eq 'install') { if (-not (Test-Path -LiteralPath $stateDir)) { New-Item -Path $stateDir -ItemType Directory -Force | Out-Null } if (-not (Test-Path -LiteralPath $stateFile)) { $original = @() foreach ($setting in $settings) { $old = Read-Value $setting.Path $setting.Name $original += [pscustomobject]@{ Path=$setting.Path; Name=$setting.Name; Exists=$old.Exists; Value=$old.Value; Target=$setting.Value } } $json = ConvertTo-Json -InputObject @($original) -Depth 5 $temp = "$stateFile.tmp" [System.IO.File]::WriteAllText($temp, $json, [System.Text.UTF8Encoding]::new($false)) Move-Item -LiteralPath $temp -Destination $stateFile -Force } foreach ($setting in $settings) { Write-Value $setting.Path $setting.Name $setting.Value } Write-Output 'Installed conservative hardening; LapsByWAPT untouched.' } elseif ($Action -eq 'audit') { $failed = @() foreach ($setting in $settings) { $actual = Read-Value $setting.Path $setting.Name if (-not $actual.Exists -or $actual.Value -ne $setting.Value) { $failed += "$($setting.Name) != $($setting.Value)" } } if ($failed.Count -gt 0) { $failed | ForEach-Object { Write-Output $_ }; exit 1 } Write-Output 'All 5 settings compliant.' } else { if (-not (Test-Path -LiteralPath $stateFile)) { throw 'No saved baseline; refusing blind rollback.' } $original = @(Get-Content -LiteralPath $stateFile -Raw | ConvertFrom-Json) foreach ($item in $original) { $current = Read-Value $item.Path $item.Name # Do not override later changes made by GPO or another administrator. if (-not $current.Exists -or $current.Value -ne [int]$item.Target) { Write-Output "Skipped externally changed setting: $($item.Name)" continue } if ($item.Exists) { Write-Value $item.Path $item.Name ([int]$item.Value) } else { Remove-ItemProperty -LiteralPath $item.Path -Name $item.Name -ErrorAction Stop } } # Keep baseline for forensic trace; uninstall is idempotent only for settings still matching targets. Write-Output 'Conditional rollback completed; LapsByWAPT untouched.' }