categories/OemSuites.ps1
|
# OEM Suites category: hardcoded ASUS/Dell/HP/Lenovo/Acer service patterns, plus a generic # heuristic detector for other non-Microsoft-signed "vendor utility"-style services # (research.md -> "OEM vendor-suite heuristic detection"). Heuristic hits are flagged # separately (HeuristicMatch = $true) and need their own confirmation (FR-017). # # ponytail: only Windows services are covered (both hardcoded and heuristic paths), not # Win32_StartupCommand registry Run-key entries - parsing every HKU/HKLM Run-key location # format robustly is a separate, larger piece of work. Upgrade if a vendor suite turns out to # rely on a Run-key autostart instead of a service. $script:OctaOemHardcodedPatterns = @( # ponytail: \bAURA\b, not a bare AURA - real -match is case-insensitive and an unanchored # substring, so bare "AURA" matched inside the Spanish word "restauracion" (as in # "reconstitution/restore"). Verified on a real Spanish-language Windows install: Microsoft's # own "Cloud backup and restore" service - "Servicio de copia de seguridad y restauracion en # la nube" - got hardcoded-pattern-matched as ASUS bloat, through the branch with NO separate # confirmation gate (unlike a HeuristicMatch hit), purely from that substring collision. Word # boundaries still match the real target correctly (confirmed: "ASUS AURA SYNC lighting # service"), just not as a substring of an unrelated word in another language. @{ Vendor = 'ASUS'; Pattern = 'Armoury Crate|ASUS.*Service|\bAURA\b|ROG Live Service|Ambient.*HAL' }, @{ Vendor = 'Dell'; Pattern = 'Dell.*Update|SupportAssist|Dell Digital Delivery' }, @{ Vendor = 'HP'; Pattern = 'HP Support Assistant|HP.*Update|HPWMISvc|HP Sure' }, @{ Vendor = 'Lenovo'; Pattern = 'Lenovo Vantage|ImController|Lenovo.*Service' }, @{ Vendor = 'Acer'; Pattern = 'Acer.*Care|Acer.*Update|Quick Access' } ) $script:OctaOemHeuristicKeywords = 'Update|Service|Assistant|Center|Tray|Helper|Agent|Monitor' function Get-OctaOemSuitesCategory { [CmdletBinding()] param() return [pscustomobject]@{ Id = 'oem-suites' DisplayName = 'OEM Suites' Description = 'ASUS/Dell/HP/Lenovo/Acer + heuristic detector' RequiresElevation = $true ContainsIrreversibleActions = $false GetActionsFunction = 'Get-OctaOemSuitesActions' ApplyActionFunction = 'Set-OctaOemSuitesAction' } } function Get-OctaOemSuitesActions { [CmdletBinding()] param() $actions = @() $allServices = @(Get-CimInstance -ClassName Win32_Service -ErrorAction SilentlyContinue) $hardcodedNames = @() foreach ($pat in $script:OctaOemHardcodedPatterns) { $matched = $allServices | Where-Object { $_.DisplayName -match $pat.Pattern -or $_.Name -match $pat.Pattern } foreach ($svc in $matched) { if ($svc.StartMode -ne 'Disabled') { $actions += New-OctaAction -TargetType Service -TargetIdentifier $svc.Name ` -CurrentValue $svc.StartMode -PlannedValue 'Disabled' -Reversible $true } $hardcodedNames += $svc.Name } } $candidates = $allServices | Where-Object { $_.StartMode -ne 'Disabled' -and $_.Name -notin $hardcodedNames -and $_.PathName } foreach ($svc in $candidates) { if ($svc.PathName -match '^"([^"]+)"') { $exePath = $Matches[1] } elseif ($svc.PathName -match '^([^\s]+\.exe)') { $exePath = $Matches[1] } else { continue } $exists = $false try { $exists = Test-Path -LiteralPath $exePath -ErrorAction Stop } catch { continue } if (-not $exists) { continue } $sig = Get-AuthenticodeSignature -LiteralPath $exePath -ErrorAction SilentlyContinue $isMicrosoft = $sig -and $sig.SignerCertificate -and ($sig.SignerCertificate.Subject -match 'O=Microsoft Corporation') if ($isMicrosoft) { continue } if ($svc.Name -match $script:OctaOemHeuristicKeywords -or $svc.DisplayName -match $script:OctaOemHeuristicKeywords) { $actions += New-OctaAction -TargetType Service -TargetIdentifier $svc.Name ` -CurrentValue $svc.StartMode -PlannedValue 'Disabled' -Reversible $true -HeuristicMatch $true } } return $actions } function Set-OctaOemSuitesAction { [CmdletBinding()] param([Parameter(Mandatory)]$Action) Set-Service -Name $Action.TargetIdentifier -StartupType Disabled } |