PowerShell has a terrific cmdlet in Get-Eventlog that makes it easy to find information in a system's event log. Since different systems may have different event logs, one of the first commands you'll want to use is this:
PS C:\> get-eventlog -list Max(K) Retain OverflowAction Entries Name ------ ------ -------------- ------- ---- 512 7 OverwriteOlder 2,125 Application 15,360 0 OverwriteAsNeeded 5,485 PowerShell 512 7 OverwriteOlder 1,829 Security 512 7 OverwriteOlder 2,139 System PS C:\>
If you run something like the following script, every single entry in the log will scroll by:
Get-Eventlog Powershell
That's probably not very practical, unless you're dumping the contents to another file.
Fortunately, the cmdlet has a parameter, -Newest that will display the last (or newest) number of log entries that you specify:
PS C:\> get-eventlog powershell -newest 5 Index Time Type Source EventID Message ----- ---- ---- ------ ------- ------- 5485 Jun 25 19:31 Info PowerShell 400 Engine state is cha 5484 Jun 25 19:31 Info PowerShell 600 Provider "Certifica 5483 Jun 25 19:31 Info PowerShell 600 Provider "Variable" 5482 Jun 25 19:31 Info PowerShell 600 Provider "Registry" 5481 Jun 25 19:31 Info PowerShell 600 Provider "Function" PS C:\>
The default table format usually ends up truncating the event message. If that happens, you can try something like:
PS C:\> get-eventlog powershell -newest 5 |format-list
Alternatively, you can try something like this:
PS C:\> get-eventlog powershell -newest 5 | ` >> select EntryType,TimeGenerated,EventID,Message | ` >> format-list >> EntryType : Information TimeGenerated : 6/25/2006 7:31:42 PM EventID : 400 Message : Engine state is changed from None to Available. Details: NewEngineState=Available PreviousEngineState=None SequenceNumber=8 HostName=ConsoleHost HostVersion=1.0.9567.1 HostId= EngineVersion=1.0.9567.1 RunspaceId= PipelineId= CommandName= CommandType= ScriptName= CommandPath= CommandLine= ...
We've truncated the output, but you get the idea.
If you're interested in a specific event id, use the Where-object cmdlet:
PS C:\> get-eventlog System -newest 5 |where {$_.EventID -eq 7036} Index Time Type Source EventID Message ----- ---- ---- ------ ------- ------- 11218 Jun 24 23:06 Info Service Control M... 7036 The PDEngine service ... 11217 Jun 24 23:00 Info Service Control M... 7036 The PDEngine service ... PS C:\>
Here we're looking for event log entries with an EventID of 7036. Notice we used -Newest to look for the last five entries. You might wonder why only two entries were returned. The answer is because the -Newest parameter is processed first and returns the last 5 entries. From within those five entries, only two had an EventID of 7036.
If you want to see the last five entries of EventID 7036 regardless of when they were logged, you have to get a little more creative:
PS C:\> $logs=get-eventlog System |where {$_.EventID -eq 7036} PS C:\> for ($i=0; $i -lt 5; $i++) {$logs[$i]} Index Time Type Source EventID Message ----- ---- ---- ------ ------- ------- 11218 Jun 24 23:06 Info Service Control M...7036 The PDEngine service 11217 Jun 24 23:00 Info Service Control M...7036 The PDEngine service 11215 Jun 24 20:19 Info Service Control M...7036 The IMAPI CD-Burning 11214 Jun 24 20:19 Info Service Control M...7036 The IMAPI CD-Burning 11212 Jun 24 20:18 Info Service Control M...7036 The IMAPI CD-Burning PS C:\>
We first dump all the logs that match our query to a variable, $logs. Then we use For to get the first five entries.
While the Get-Eventlog cmdlet is easy to use, it can only be used on the local system. If you want to query event logs on remote systems, you'll need to use WMI and the Get-Wmiobject cmdlet:
PS C:\> $credential=get-credential cmdlet get-credential at command pipeline position 1 Supply values for the following parameters: Credential PS C:\> get-wmiobject win32_NTEventlogfile ` >> -computer DC01 -credential $credential | ` >> select-object FileSize,LogFileName,NumberOfRecords |` >> format-table -autosize >> FileSize LogFileName NumberOfRecords -------- ----------- --------------- 720896 Application 3617 524288 Directory Service 2712 6291456 DNS Server 32861 65536 File Replication Service 124 134217728 Security 331683 5177344 System 22345 PS C:\>
In this example we used alternate credentials and create a variable to hold them. We then run Get-Wmiobject for the remote system and get instances of Win32_NTEventlogfile. We selected a few properties and formatted the output. The expression above is similar to Get-Eventlog -list.
Event log entries belong to the Win32_NTLogEvent WMI class. To query logs via WMI, you need specify at least the logfile name and preferably more. Here's our earlier event log query rewritten to use Get-Wmiobject on a remote system:
PS C:\> get-wmiobject win32_NTLogEvent -computer DC01 -credential ` >> $credential | where ` >> {$_.logfile -eq "System" -AND $_.EventCode -eq "7036"} |` >> select-object TimeGenerated,Message | format-table -autosize >> #output truncated for display purposes 20050331092522.000000-300 The Network Location Awareness (NLA) service 20050331092522.000000-300 The Distributed File System service entered 20050331085717.000000-300 The WinHTTP Web Proxy Auto-Discovery Service 20050331085320.000000-300 The Windows Installer service entered the st 20050331084607.000000-300 The World Wide Web Publishing Service servic 20050331084606.000000-300 The World Wide Web Publishing Service servic 20050331084047.000000-300 The WinHTTP Web Proxy Auto-Discovery Service 20050331083404.000000-300 The Windows Installer service entered the ru 20050331082950.000000-300 The Network Connections service entered the 20050330172042.000000-300 The Network Location Awareness (NLA) service PS C:\>
Depending on the number of log entries, this expression may take several minutes to run before anything appears. Occasionally nothing is displayed even though there are records that meet the query criteria. As we've mentioned before, WMI support in PowerShell is not foolproof at this stage. However, we expect improvements and enhanced support for WMI.