public/Get-OctaCategory.ps1
|
# Registry of all category metadata functions (data-model.md -> Category). Each entry names # the function (defined in categories/*.ps1) that returns that category's metadata object. $script:OctaCategoryFunctions = @( 'Get-OctaTelemetryCategory', 'Get-OctaAppxCategory', 'Get-OctaOneDriveCategory', 'Get-OctaCopilotCategory', 'Get-OctaWidgetsCategory', 'Get-OctaRecallCategory', 'Get-OctaExplorerStartCategory', 'Get-OctaOemSuitesCategory', 'Get-OctaPerformanceCategory', 'Get-OctaPowerCategory', 'Get-OctaUserExperienceCategory', 'Get-OctaGpuCategory', 'Get-OctaServicesCategory', 'Get-OctaDesktopCategory', 'Get-OctaPreferencesCategory', 'Get-OctaGamingCategory', 'Get-OctaAiFeaturesCategory', 'Get-OctaWindowsFeaturesCategory', 'Get-OctaBackgroundActivityCategory', 'Get-OctaRegistryOrphansCategory' ) $script:OctaRiskRank = @{ Safe = 0; Moderate = 1; Risky = 2 } function Get-OctaCategory { <# .SYNOPSIS Lists all Octa categories, or a single one by Id. HighestRiskLevel is computed here from a live scan (GetActionsFunction), not stored statically on the category, so it always reflects current machine state - FR-027. #> [CmdletBinding()] param( [string]$Id ) # ponytail: when -Id is given, only resolve/scan the requested category - not every # registered one. Metadata functions are cheap (a static object literal), so calling them # all just to filter by Id costs nothing; the expensive part is GetActionsFunction, which # this skips for every non-matching category. Found because Invoke-OctaCategory calls this # once per bundle member - Quick Clean (7 categories after 006's appx/oem-suites addition) # was doing 7 x 18 full scans instead of 7, taking minutes instead of seconds. $functionNames = $script:OctaCategoryFunctions if ($Id) { $functionNames = $script:OctaCategoryFunctions | Where-Object { (& $_).Id -eq $Id } } $categories = $functionNames | ForEach-Object { $category = & $_ $highest = 'Safe' try { # A category's scan can legitimately require elevation (e.g. Appx's # Get-AppxPackage -AllUsers) - Get-OctaCategory has no elevation gate of its own # (that only happens in Invoke-OctaCategory before an actual apply/dry-run), so a # scan failure here must not crash a plain `--list` for a non-elevated user. $actions = @(& $category.GetActionsFunction) foreach ($action in $actions) { if ($script:OctaRiskRank[$action.RiskLevel] -gt $script:OctaRiskRank[$highest]) { $highest = $action.RiskLevel } } } catch { $highest = 'Unknown' } Add-Member -InputObject $category -MemberType NoteProperty -Name 'HighestRiskLevel' -Value $highest -Force $category } return $categories } |