To audit all shutdown/restart events across Windows Server 2008 through 2012 R2, you'll need to monitor these critical Event IDs in the System log:
// PowerShell query to get shutdown/restart events
Get-WinEvent -LogName System | Where-Object {
$_.Id -eq 1074 -or # User-initiated shutdown
$_.Id -eq 1076 -or # Shutdown after hung app
$_.Id -eq 6006 -or # System shutdown (clean)
$_.Id -eq 6008 -or # Unexpected shutdown
$_.Id -eq 41 -or # Kernel power critical error
$_.Id -eq 109 -or # Kernel event tracing
$_.Id -eq 1001 # Windows Error Reporting
} | Format-Table TimeCreated, Id, Message -AutoSize
- Event 1074: Records user-initiated shutdowns/restarts including the initiating user and reason code
- Event 6006: Clean shutdown logged by EventLog service before termination
- Event 6008: Indicates improper shutdown (last shutdown was unexpected)
- Event 41: Kernel-power critical error (system crashed/froze)
For a comprehensive report with parsed XML data:
# Advanced PowerShell query with XML parsing
$query = @'
<QueryList>
<Query Id="0" Path="System">
<Select Path="System">
*[System[
(EventID=1074) or
(EventID=1076) or
(EventID=6006) or
(EventID=6008) or
(EventID=41)
]]
</Select>
</Query>
</QueryList>
'@
Get-WinEvent -FilterXml $query | ForEach-Object {
[PSCustomObject]@{
Time = $_.TimeCreated
EventID = $_.Id
User = $_.Properties[6].Value
Process = $_.Properties[0].Value
Reason = $_.Properties[4].Value
Comment = $_.Properties[5].Value
}
} | Format-Table -AutoSize
Create a scheduled task to log shutdown events to CSV:
# Save as TrackShutdowns.ps1
$logPath = "C:\ShutdownLogs\shutdown_history.csv"
$events = Get-WinEvent -FilterHashtable @{
LogName = 'System'
ID = 1074,6006,6008,41
} -MaxEvents 50
$events | Select-Object TimeCreated, Id,
@{Name='User';Expression={$_.Properties[6].Value}},
@{Name='Type';Expression={
switch ($_.Id) {
1074 {'User Initiated'}
6006 {'Clean Shutdown'}
6008 {'Unexpected'}
41 {'Crash'}
}
}},
@{Name='Reason';Expression={$_.Properties[4].Value}}
| Export-Csv -Path $logPath -NoTypeInformation -Append
Common reason codes in Event 1074:
Code | Meaning |
---|---|
0x80020002 | Planned maintenance |
0x80020003 | Hardware installation |
0x80010001 | Security update |
0x800000ff | Blue screen crash |
To comprehensively track all shutdown/restart events across Windows Server versions (2008 through 2012 R2), you'll need to monitor these key Event IDs:
- Event ID 1074: User-initiated shutdown/restart (includes user context and reason)
- Event ID 6006: Clean shutdown logged by EventLog service
- Event ID 6008: Unexpected shutdown (crash or power loss)
- Event ID 41: Kernel power critical error (unexpected reboot)
- Event ID 4608: Windows startup (for reboot tracking)
Here's a robust PowerShell script that retrieves all shutdown-related events from multiple logs:
# Define the Event IDs to query
$eventIds = @(1074, 6006, 6008, 41, 4608)
# Query System and Application logs
$events = Get-WinEvent -LogName 'System','Application' |
Where-Object { $_.Id -in $eventIds } |
Sort-Object TimeCreated -Descending
# Format the output
$events | ForEach-Object {
$props = @{
Time = $_.TimeCreated
EventID = $_.Id
Source = $_.ProviderName
Message = $_.Message
}
New-Object -TypeName PSObject -Property $props
} | Format-Table -AutoSize
For deeper analysis of intentional shutdowns (Event ID 1074), use this enhanced query:
$shutdownEvents = Get-WinEvent -FilterHashtable @{
LogName = 'System'
ID = 1074
} | Select-Object TimeCreated,
@{Name='User';Expression={$_.Properties[6].Value}},
@{Name='Action';Expression={$_.Properties[4].Value}},
@{Name='Reason';Expression={$_.Properties[2].Value}}
For long-term tracking, consider this CSV export solution with scheduled task integration:
# Set date range (last 90 days)
$startDate = (Get-Date).AddDays(-90)
$endDate = Get-Date
$output = @()
Get-WinEvent -FilterHashtable @{
LogName = 'System'
ID = @(1074,6006,6008,41)
StartTime = $startDate
EndTime = $endDate
} | ForEach-Object {
$output += [PSCustomObject]@{
Timestamp = $_.TimeCreated
EventID = $_.Id
Type = switch ($_.Id) {
1074 { 'User Initiated' }
6006 { 'Clean Shutdown' }
6008 { 'Unexpected Shutdown' }
41 { 'Kernel Power Failure' }
}
User = if ($_.Id -eq 1074) { $_.Properties[6].Value } else { 'System' }
Reason = if ($_.Id -eq 1074) { $_.Properties[2].Value } else { $_.Message }
}
}
# Export to CSV with timestamp
$output | Export-Csv -Path "C:\ShutdownHistory_$(Get-Date -Format 'yyyyMMdd').csv" -NoTypeInformation
Understanding the reason codes in Event ID 1074 is crucial for root cause analysis:
- 0x80020002: Operating System: Service Pack (Planned)
- 0x80020003: Operating System: Upgrade (Planned)
- 0x80020004: Operating System: Reconfiguration (Planned)
- 0x80020008: Application: Maintenance (Planned)
- 0x8002000c: Application: Unstable
Create a scheduled task to run this PowerShell script daily:
$action = New-ScheduledTaskAction -Execute 'PowerShell.exe' `
-Argument '-NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\ShutdownMonitor.ps1"'
$trigger = New-ScheduledTaskTrigger -Daily -At 3am
Register-ScheduledTask -TaskName "Shutdown Event Monitor" `
-Action $action -Trigger $trigger -User "SYSTEM" -RunLevel Highest
For Windows Server 2008/R2, you might need to adjust the Property indices in Event ID 1074 parsing as the message structure slightly differs from newer versions. Always test your scripts in each target environment.