powershell.exe -File binds a single-quoted comma list like '00','03','05' as ONE string element, not a [string[]] array, so Invoke-Hardening.ps1's -contains filter matched nothing and all hardening modules were silently skipped. Fix: adopt a CSV-split contract — Invoke-Hardening.ps1 now accepts [string]$Modules and splits on ',' internally ($ModuleList = $Modules -split ','); ApplyService passes a bare CSV token (e.g. 00,03,05) with no surrounding quotes. Empirically verified via ProcessStartInfo: candidate (a) '00','03','05' → COUNT=1 (bug); candidate (b) 00,03,05 → single string, correctly split by the script; candidate (c) space-separated → PS positional-parameter error. PARSE OK confirmed. Adds ApplyServiceHardeningIntegrationTests: copies the real Invoke-Hardening.ps1 into a temp dir with harmless dummy 0*.ps1 stubs, runs ApplyService with the real ProcessRunner for modules ["00","05"], and asserts ran.txt contains RAN 00 and RAN 05 but NOT RAN 03 or RAN 07. Test fails on the old encoding and passes with the fix (regression-checked).
22 lines
1.2 KiB
PowerShell
22 lines
1.2 KiB
PowerShell
#Requires -Version 5.1
|
|
<# Runs the §A-H modules (optionally a subset) then Verify.
|
|
-Modules "00","03","05" -> run only those numeric-prefixed modules (default: all 0*).
|
|
-ParamsJson '{"wdac":"audit"}' -> exported as $env:SM_PARAMS for modules to read. #>
|
|
[CmdletBinding()] param([string]$Modules, [string]$ParamsJson)
|
|
$ErrorActionPreference = 'Continue'
|
|
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
if ($ParamsJson) { $env:SM_PARAMS = $ParamsJson }
|
|
# Accept Modules as a single CSV token (e.g. "00,03,05") so that ProcessStartInfo
|
|
# -File binding delivers it reliably as one string regardless of quoting.
|
|
$ModuleList = if ($Modules) { $Modules -split ',' } else { @() }
|
|
Write-Host "=== SilverMetal hardening modules ==="
|
|
$all = Get-ChildItem (Join-Path $here '0*.ps1') | Sort-Object Name
|
|
if ($ModuleList.Count -gt 0) { $all = $all | Where-Object { $ModuleList -contains $_.Name.Substring(0,2) } }
|
|
foreach ($f in $all) {
|
|
Write-Host "--> $($f.Name)"
|
|
try { & $f.FullName } catch { Write-Warning "$($f.Name) FAILED: $_" }
|
|
}
|
|
Write-Host "=== Verify ==="
|
|
try { & (Join-Path $here 'Verify-SilverMetalWindows.ps1') } catch { Write-Warning "Verify error: $_" }
|
|
Write-Host "=== runner done ==="
|