Functions/SystemAudit/Get-SystemAuditWindowsService.ps1
<#
.SYNOPSIS Get all audit events of the Windows services. .DESCRIPTION This function will show all Windows service audit changes on the target system by parsing the following Application events: - 7000: Service Start Failed - 7001: Service Dependency Start Failed - 7011: Service Start/Stop Timeout - 7023: Service Terminated - 7026: Boot/System-Start Driver Not Loaded - 7030: Service Configuration Error: Interactive Service Configured but not Allowed - 7034: Service Terminated Unexpectedly - 7038: Service Configuration Error: Unable to Log-On - 7040: Service Changed: Start Type Updated - 7045: Service Installed .INPUTS None. .OUTPUTS SecurityFever.SystemAudit.Event. .EXAMPLE PS C:\> Get-SystemAuditWindowsService Get the local Windows service system audit events. .LINK https://github.com/claudiospizzi/SecurityFever #> function Get-SystemAuditWindowsService { [CmdletBinding()] [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '')] param ( # Period of days to cover. [Parameter(Mandatory = $false)] [System.Int32] $DayPeriod = 7, # Show extended events, not only the important ones. [Parameter(Mandatory = $false)] [Switch] $Extended, # Hide the warning messages, don't test the prerequisites. [Parameter(Mandatory = $false)] [Switch] $HideWarning ) Show-SystemAuditEventLogWarning -LogName 'System' -DayPeriod $DayPeriod -HideWarning:$HideWarning.IsPresent $configEventLog = Get-Content -Path "$Script:ConfigurationPath\SystemAudit.EventLog.json" | ConvertFrom-Json # Get all relevant event log records for the MSI Installer $records = Get-WinEventAdvanced -LogName 'System' -EventId 7000, 7001, 7011, 7023, 7026, 7030, 7034, 7038, 7040, 7045 -ProviderName 'Service Control Manager' -DayPeriod $DayPeriod foreach ($record in $records) { $recordId = $record.Id $auditEvent = [PSCustomObject] @{ PSTypeName = 'SecurityFever.SystemAudit.Event' Timestamp = $record.TimeCreated Machine = $record.MachineName User = Get-WinEventRecordUser -Record $record Component = 'Windows Service' Action = $configEventLog.Events.System.$recordId.Action Context = $record.Properties[0].Value Detail = '' SourcePath = '/EventLog/Application/Record[@Id={0}]' -f $recordId SourceEvent = $record } # Fix the context for events where the service name is not stored in the # first property. if ($recordId -eq 7011) { $auditEvent.Context = $record.Properties[1].Value } # Enhance the service audit records with additional details. if ($recordId -eq 7000) { $auditEvent.Detail = 'Error: {0}' -f (Get-WinEventWin32Exception -ErrorCode $record.Properties[1].Value) } if ($recordId -eq 7001) { $auditEvent.Detail = 'Depending Service: {0}, Error: {1}' -f $record.Properties[1].Value, (Get-WinEventWin32Exception -ErrorCode $record.Properties[2].Value) } if ($recordId -eq 7011) { $auditEvent.Detail = 'Timeout: {0}ms' -f $record.Properties[1].Value } if ($recordId -eq 7023) { $auditEvent.Detail = 'Error: {0}' -f (Get-WinEventWin32Exception -ErrorCode $record.Properties[1].Value) } if ($recordId -eq 7034) { $auditEvent.Detail = 'Count: {0}' -f $record.Properties[1].Value } if ($recordId -eq 7038) { $auditEvent.Detail = 'User: {0}, Error: {1}' -f $record.Properties[1].Value, (Get-WinEventWin32Exception -ErrorCode $record.Properties[2].Value) } if ($recordId -eq 7040) { $auditEvent.Detail = 'Old: {0}, New: {1}' -f $record.Properties[1].Value, $record.Properties[2].Value } if ($recordId -eq 7045) { $auditEvent.Detail = 'Path: {0}, Type: {1}, Start: {2}, User: {3}' -f $record.Properties[1].Value, $record.Properties[2].Value, $record.Properties[3].Value, $record.Properties[4].Value } Write-Output $auditEvent } } |