Fix run reports and Windows Home policy planning
Windows tests / test-and-build (push) Canceled after 0s

This commit is contained in:
0x000 committed 2026-09-23 18:49:13 -04:00
1 parent 942b849306
commit 22d06ac7fd
19 files changed
+72 -43

No files matched your search

+5 -5
View File
@@ -17,7 +17,7 @@ function Invoke-MsPrivateGroupPlan {
}
$entries=@($Groups|ForEach-Object{[pscustomobject]@{Id=[string]$_.Id;Label=[string]$_.Label;DependsOn=@($_.DependsOn);Status='Pending';Error=$null}})
$report=[pscustomobject]@{Schema=1;Kind='MsPrivateRun';CreatedUtc=[DateTime]::UtcNow.ToString('o');CompletedUtc=$null;Status='Running';Entries=$entries}
$save={if($ReportPath){Write-MsPrivateJsonAtomic -InputObject $report -Path $ReportPath -Depth 8}}.GetNewClosure();&$save
if($ReportPath){Write-MsPrivateJsonAtomic -InputObject $report -Path $ReportPath -Depth 8}
foreach($group in $Groups){
$entry=@($entries | Where-Object { $_.Id -ceq [string]$group.Id })[0]
$blocked=@($entry.DependsOn | Where-Object {
@@ -25,14 +25,14 @@ function Invoke-MsPrivateGroupPlan {
$dependencyEntry=@($entries | Where-Object { $_.Id -ceq $dependency })
$dependencyEntry.Count -ne 1 -or $dependencyEntry[0].Status -ne 'Succeeded'
})
if($blocked.Count){$entry.Status='SkippedDependency';$entry.Error='Required group did not succeed: '+($blocked-join', ');&$save;continue}
$entry.Status='Running';&$save;if($OnProgress){&$OnProgress $entry}
if($blocked.Count){$entry.Status='SkippedDependency';$entry.Error='Required group did not succeed: '+($blocked-join', ');if($ReportPath){Write-MsPrivateJsonAtomic -InputObject $report -Path $ReportPath -Depth 8};continue}
$entry.Status='Running';if($ReportPath){Write-MsPrivateJsonAtomic -InputObject $report -Path $ReportPath -Depth 8};if($OnProgress){&$OnProgress $entry}
try{& $group.Action|Out-Host;$entry.Status='Succeeded'}catch{$entry.Status='Failed';$entry.Error=$_.Exception.Message}
&$save
if($ReportPath){Write-MsPrivateJsonAtomic -InputObject $report -Path $ReportPath -Depth 8}
}
$failed=@($entries | Where-Object { $_.Status -eq 'Failed' }).Count
$skipped=@($entries | Where-Object { $_.Status -eq 'SkippedDependency' }).Count
$report.Status=if($failed-or$skipped){'PartialFailure'}else{'Completed'};$report.CompletedUtc=[DateTime]::UtcNow.ToString('o');&$save
$report.Status=if($failed-or$skipped){'PartialFailure'}else{'Completed'};$report.CompletedUtc=[DateTime]::UtcNow.ToString('o');if($ReportPath){Write-MsPrivateJsonAtomic -InputObject $report -Path $ReportPath -Depth 8}
$report
}
+10 -2
View File
@@ -30,6 +30,7 @@ function Get-WindCatalog {
if($registryPath-notmatch'^(SOFTWARE|SYSTEM)\\[A-Za-z0-9 _.-]+(?:\\[A-Za-z0-9 _.-]+)*$'-or$registryPath-match'(^|\\)\.\.?($|\\)'){throw "Invalid policy registry path: $id"}
if($name-notmatch'^[A-Za-z0-9_]+$'-or$targets.ContainsKey($target)){throw "Invalid or duplicate policy registry target: $id"}
foreach($profile in @('Standard','Strict')){$value=$item.$profile;if($null-eq$value){continue};if($value-isnot[ValueType]-or[double]$value-ne[int]$value-or[int]$value-lt0){throw "Invalid $profile policy value: $id"}}
if($item.PSObject.Properties['HomeSupported']-and$item.HomeSupported-isnot[bool]){throw "HomeSupported must be a Boolean: $id"}
if($null-ne$item.EnterpriseValue-and($item.EnterpriseValue-isnot[ValueType]-or[double]$item.EnterpriseValue-ne[int]$item.EnterpriseValue-or[int]$item.EnterpriseValue-lt0)){throw "Invalid Enterprise policy value: $id"}
if($null-eq$item.Standard-and$null-eq$item.Strict-and$null-eq$item.EnterpriseValue-and$id-notin@('updates-auto','updates-options')){throw "Policy has no selectable value: $id"}
$source=$null;if(-not[uri]::TryCreate([string]$item.Source,[UriKind]::Absolute,[ref]$source)-or$source.Scheme-ne'https'){throw "Policy requires an HTTPS source: $id"}
@@ -116,6 +117,7 @@ function Get-WindPlan {
if ($catalog.Id -notcontains $item) { throw "Unknown policy ID: $item" }
}
$supportedEdition = $Context.Edition -in @('Professional','ProfessionalN','ProfessionalEducation','ProfessionalEducationN','ProfessionalWorkstation','ProfessionalWorkstationN','Enterprise','EnterpriseN','Education','EducationN','EnterpriseS','EnterpriseSN')
$homeEdition = $Context.Edition -in @('Core','CoreN','CoreSingleLanguage','CoreCountrySpecific')
$supportedBuild = $Context.Build -in @(26100,26200)
foreach ($policy in $catalog) {
if ($Id.Count -gt 0 -and $Id -notcontains $policy.Id) { continue }
@@ -138,9 +140,15 @@ function Get-WindPlan {
$status = 'Conflict'; $reason = 'Existing per-app exceptions need review; default deny would not cover all apps.'
}
}
if (-not $supportedEdition -or -not $supportedBuild) {
$homeSupported=$policy.PSObject.Properties['HomeSupported']-and[bool]$policy.HomeSupported
if (-not $supportedBuild) {
$status = 'Unsupported'
$reason = 'This edition/build is audit-only. Registry presence does not establish policy enforcement; use Guide.'
$reason = 'This Windows build is not reviewed for policy application. Registry presence does not establish enforcement.'
} elseif (-not $supportedEdition -and-not($homeEdition-and$homeSupported)) {
$status = 'Unsupported'
$reason = if($homeEdition){'Microsoft documents this policy for managed Pro/Enterprise/Education editions, not Windows Home. Use the Home guide.'}else{'This Windows edition is not reviewed for policy application.'}
} elseif($homeEdition-and$homeSupported) {
$reason = 'Microsoft documents this direct registry control independently of the managed-edition CSP. Behavioral verification remains required on Home.'
}
} catch {
$status = 'ReadError'; $reason = 'Could not read policy state. No protection can be inferred.'
+4 -2
View File
@@ -126,7 +126,8 @@ function Get-WindSetupSnapshot {
$options=$Settings.AppOptions
$sensors=@();if($Settings.DisableSensors){$sensors=@(Get-WindSensorInventory|Where-Object Status -eq 'OK')}
$recallPlan=if($Settings.Recall){Get-WindRecallPlan -RemoveFeature:$Settings.RemoveRecall}else{$null}
[pscustomobject]@{Apps=@(Get-WindAppPlan -Inventory $inventory @options);Policies=@(Get-WindPlan -Context (Get-WindContext) -Store (New-WindRegistryStore) -Profile $Settings.Profile -Updates $Settings.Updates);Sensors=$sensors;Recall=$recallPlan}
$context=Get-WindContext
[pscustomobject]@{Context=$context;Apps=@(Get-WindAppPlan -Inventory $inventory @options);Policies=@(Get-WindPlan -Context $context -Store (New-WindRegistryStore) -Profile $Settings.Profile -Updates $Settings.Updates);Sensors=$sensors;Recall=$recallPlan}
}
function Show-WindSetupReview {
param($Snapshot,$Settings)
@@ -135,7 +136,8 @@ function Show-WindSetupReview {
foreach ($a in @($Snapshot.Apps | Where-Object Status -ne 'Keep')) {$items+=New-WindMenuItem $a.Id ("[$($a.Status)] $($a.Name)") ("$($a.Scope) scope. $($a.Reason). App data may be removed by the uninstaller.") $true}
foreach($s in @($Snapshot.Sensors)){$items+=New-WindMenuItem ('sensor:'+ $s.InstanceId) ("[WouldDisable] $($s.Kind): $($s.Name)") $s.Risk $true}
if($Snapshot.Recall){foreach($r in $Snapshot.Recall.Items){$items+=New-WindMenuItem ('recall:'+ $r.Id) ("[$($r.Status)] $($r.Action)") $r.Impact $true}}
Select-WindMenu -Title 'Review your plan' -Subtitle ("$($Settings.Preset) | $($Settings.Profile) | Apps: $(@($Snapshot.Apps|Where-Object Status -eq 'Remove').Count) | Sensors: $(@($Snapshot.Sensors).Count) | Network: $($Settings.Network)") -Items $items -Searchable | Out-Null
$available=@($Snapshot.Policies|Where-Object {$_.Status-in@('WouldChange','Configured')}).Count;$unsupported=@($Snapshot.Policies|Where-Object {$_.Status-eq'Unsupported'}).Count
Select-WindMenu -Title 'Review your plan' -Subtitle ("$($Snapshot.Context.Edition) $($Snapshot.Context.Build) | $available policies available / $unsupported unsupported | Apps: $(@($Snapshot.Apps|Where-Object Status -eq 'Remove').Count) | Network: $($Settings.Network)") -Items $items -Searchable | Out-Null
}
function Set-WindSetupPreset {
param($Settings,$Preset)