Functions/SystemAudit/Get-SystemAuditPowerCycle.ps1
<#
.SYNOPSIS Get all audit events around the power cycle of the local system. .DESCRIPTION This function will show all power cycle events on the target system by parsing the following System events: - 1: Leaving Sleep - 42: Entering Sleep - 1074: Request System Restart / Power Off - 6005: System Startup - 6006: System Shutdown - 6008: Unexpected Shutdown .INPUTS None. .OUTPUTS SecurityFever.SystemAudit.Event. .EXAMPLE PS C:\> Get-SystemAuditPowerCycle Get the local power cycle system audit events. .LINK https://github.com/claudiospizzi/SecurityFever #> function Get-SystemAuditPowerCycle { [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 power cycle. Refer to the # description for the event id explanation. $records = Get-WinEventAdvanced -LogName 'System' -EventId 1, 42, 1074, 6005, 6006, 6008 -ProviderName 'Microsoft-Windows-Kernel-Power', 'Microsoft-Windows-Power-Troubleshooter', 'User32', 'EventLog' -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 = 'System Power' Action = $configEventLog.Events.System.$recordId.Action Context = '' Detail = '' SourcePath = '/EventLog/System/Record[@Id={0}]' -f $recordId SourceEvent = $record } # Try to get the reason for sleep and awake action if ($recordId -eq 1) { switch ($record.Properties[12].Value) { 1 { $auditEvent.Detail = 'Reason: Power Button' } 3 { $auditEvent.Detail = 'Reason: S4 Doze to Hibernate' } 5 { $auditEvent.Detail = 'Reason: Device - ACPI Lid' } } } if ($recordId -eq 42) { switch ($record.Properties[2].Value) { 0 { $auditEvent.Detail = 'Reason: Button or Lid' } 2 { $auditEvent.Detail = 'Reason: Battery' } 4 { $auditEvent.Detail = 'Reason: Application API' } 6 { $auditEvent.Detail = 'Reason: Hibernate from Sleep - Fixed Timeout' } 7 { $auditEvent.Detail = 'Reason: System Idle' } } } # Add additional info to the reboot or power off request if ($recordId -eq 1074) { $auditEvent.Detail = 'Process: {0}' -f $record.Properties[0].Value.ToLower() $auditEvent.Action = $auditEvent.Action -f [System.Globalization.CultureInfo]::InvariantCulture.TextInfo.ToTitleCase($Record.Properties[4].Value) } # Update the date for the unexpected reboot if ($recordId -eq 6008) { # Helper char, must be removed from the date property $lrMark = [char]8206 $timestamp = '{0} {1}' -f $record.Properties[1].Value.Replace("$lrMark", ""), $record.Properties[0].Value try { $auditEvent.Timestamp = [System.DateTime]::Parse($timestamp) $auditEvent.Detail = "Event Created: {0}" -f $record.TimeCreated } catch { Write-Warning "Failed to parse timestamp $timestamp for System event id 6008: $_" } } Write-Output $auditEvent } } |