categories/Services.ps1
|
# Services category: curated, risk-rated optional-service catalog (research.md - 36 services # cross-referenced against multiple independent public sources). Not already covered by # telemetry/oem-suites - FR-037. # # 008: DoSvc (Delivery Optimization) removed from the generic Service-typed catalog above - # confirmed during 006's VM validation that Set-Service is rejected by DoSvc's ACL even under a # full admin token (Microsoft intentionally steers DoSvc configuration through Group Policy, not # the service control API). Replaced below with a Registry-typed action targeting the documented # DODownloadMode Group Policy key instead - see Get-OctaServicesActions/Set-OctaServicesAction. $script:OctaServicesCatalog = @( # Safe - target Disabled, no working-functionality loss if genuinely unused @{ Name = 'MapsBroker'; Target = 'Disabled'; RiskLevel = 'Safe' } @{ Name = 'WpcMonSvc'; Target = 'Disabled'; RiskLevel = 'Safe' } @{ Name = 'PhoneSvc'; Target = 'Disabled'; RiskLevel = 'Safe' } @{ Name = 'RetailDemo'; Target = 'Disabled'; RiskLevel = 'Safe' } @{ Name = 'wisvc'; Target = 'Disabled'; RiskLevel = 'Safe' } @{ Name = 'icssvc'; Target = 'Disabled'; RiskLevel = 'Safe' } @{ Name = 'XboxGipSvc'; Target = 'Disabled'; RiskLevel = 'Safe' } @{ Name = 'XblAuthManager'; Target = 'Disabled'; RiskLevel = 'Safe' } @{ Name = 'XblGameSave'; Target = 'Disabled'; RiskLevel = 'Safe' } @{ Name = 'XboxNetApiSvc'; Target = 'Disabled'; RiskLevel = 'Safe' } @{ Name = 'Fax'; Target = 'Disabled'; RiskLevel = 'Safe' } @{ Name = 'WalletService'; Target = 'Disabled'; RiskLevel = 'Safe' } @{ Name = 'TabletInputService'; Target = 'Disabled'; RiskLevel = 'Safe' } @{ Name = 'lfsvc'; Target = 'Disabled'; RiskLevel = 'Safe' } @{ Name = 'WerSvc'; Target = 'Disabled'; RiskLevel = 'Safe' } @{ Name = 'SCardSvr'; Target = 'Disabled'; RiskLevel = 'Safe' } @{ Name = 'ScDeviceEnum'; Target = 'Disabled'; RiskLevel = 'Safe' } @{ Name = 'SCPolicySvc'; Target = 'Disabled'; RiskLevel = 'Safe' } @{ Name = 'BTAGService'; Target = 'Disabled'; RiskLevel = 'Safe' } @{ Name = 'bthserv'; Target = 'Disabled'; RiskLevel = 'Safe' } @{ Name = 'SensorService'; Target = 'Disabled'; RiskLevel = 'Safe' } @{ Name = 'WbioSrvc'; Target = 'Disabled'; RiskLevel = 'Safe' } @{ Name = 'DevicePickerUserSvc'; Target = 'Disabled'; RiskLevel = 'Safe'; IsUserTemplate = $true } # Moderate - target Manual, real functionality trade-off if actually used @{ Name = 'Spooler'; Target = 'Manual'; RiskLevel = 'Moderate' } @{ Name = 'DPS'; Target = 'Manual'; RiskLevel = 'Moderate' } @{ Name = 'WdiServiceHost'; Target = 'Manual'; RiskLevel = 'Moderate' } @{ Name = 'WdiSystemHost'; Target = 'Manual'; RiskLevel = 'Moderate' } @{ Name = 'DiagsSvc'; Target = 'Manual'; RiskLevel = 'Moderate' } @{ Name = 'SessionEnv'; Target = 'Manual'; RiskLevel = 'Moderate' } @{ Name = 'TermService'; Target = 'Manual'; RiskLevel = 'Moderate' } @{ Name = 'UmRdpService'; Target = 'Manual'; RiskLevel = 'Moderate' } @{ Name = 'WorkFolders'; Target = 'Manual'; RiskLevel = 'Moderate' } @{ Name = 'Netlogon'; Target = 'Manual'; RiskLevel = 'Moderate' } # Risky - real, narrow chance of a serious problem @{ Name = 'BDESVC'; Target = 'Disabled'; RiskLevel = 'Risky' } @{ Name = 'AssignedAccessManagerSvc'; Target = 'Disabled'; RiskLevel = 'Risky' } ) function Get-OctaServicesCategory { [CmdletBinding()] param() return [pscustomobject]@{ Id = 'services' DisplayName = 'Services' Description = 'Curated, risk-rated optional Windows services' RequiresElevation = $true ContainsIrreversibleActions = $false GetActionsFunction = 'Get-OctaServicesActions' ApplyActionFunction = 'Set-OctaServicesAction' } } function Get-OctaServicesActions { [CmdletBinding()] param() $actions = @() foreach ($entry in $script:OctaServicesCatalog) { if ($entry.IsUserTemplate) { $matches = @(Get-CimInstance -ClassName Win32_Service -ErrorAction SilentlyContinue | Where-Object { $_.Name -match "^$($entry.Name)_" }) } else { $matches = @(Get-CimInstance -ClassName Win32_Service -Filter "Name='$($entry.Name)'" -ErrorAction SilentlyContinue) } foreach ($svc in $matches) { if ($svc.StartMode -eq $entry.Target) { continue } $actions += New-OctaAction -TargetType Service -TargetIdentifier $svc.Name ` -CurrentValue $svc.StartMode -PlannedValue $entry.Target -Reversible $true -RiskLevel $entry.RiskLevel } } # Delivery Optimization via Group Policy (008) - see file header comment for why this isn't # a Set-Service call like everything else above. $doKey = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\DeliveryOptimization' $doMode = (Get-ItemProperty -Path $doKey -Name 'DODownloadMode' -ErrorAction SilentlyContinue).DODownloadMode if ($doMode -ne 0) { $displayCurrent = if ($null -eq $doMode) { '(not set)' } else { $doMode } $actions += New-OctaAction -TargetType Registry -TargetIdentifier "$doKey|DODownloadMode" ` -CurrentValue $displayCurrent -PlannedValue 0 -Reversible $true -RiskLevel Moderate } return $actions } function Set-OctaServicesAction { [CmdletBinding()] param([Parameter(Mandatory)]$Action) if ($Action.TargetType -eq 'Registry') { $keyPath, $valueName = $Action.TargetIdentifier -split '\|', 2 if (-not (Test-Path $keyPath)) { New-Item -Path $keyPath -Force | Out-Null } Set-ItemProperty -Path $keyPath -Name $valueName -Value $Action.PlannedValue -Type DWord return } Set-Service -Name $Action.TargetIdentifier -StartupType $Action.PlannedValue } |