Categories

Scripting Games 2012 comments: #9 Beginners event 5

Beginners event 5

http://blogs.technet.com/b/heyscriptingguy/archive/2012/04/06/2012-scripting-games-beginner-event-5-provide-a-source-and-errors.aspx

Looking for problem applications. Need report from each server form application log listing source and number of errors.

Requirements:

  • should be capable of running against remote machine
  • doesn't need to run remotely for this scenario
  • don't need to check for admin rights
  • assume have permissions to query application log
  • use standard PowerShell cmdlets
  • solution should be simple and straightforward
  • don't need to write to text file BUT should should be easily redirectable when needed
  • don't need comment based help
  • extra points for sorting so source with greatest number of errors at top of list

Reading the event log using standard PowerShell cmdlets -  what do we have available?

Get-Command *event* -CommandType cmdlet

shows a bunch of cmdlets. Lets narrow it down

Get-Command *eventlog* -CommandType cmdlet

shows that Get-EventLog is a good choice.

NOTE: Get-WinEvent is also available but the syntax can be more convoluted. As we are reading a classic event log Get-Eventlog is the simplest solution.

What parameters do we have available?

PS> Get-Help Get-EventLog

NAME
    Get-EventLog

SYNOPSIS
    Gets the events in an event log, or a list of the event logs, on the local or remote computers.


SYNTAX
 

Get-EventLog [-AsString] [-ComputerName <string[]>] [-List] [<CommonParameters>]

Get-EventLog [-LogName] <string> [[-InstanceId] <Int64[]>] [-After <DateTime>] [-AsBaseObject]
[-Before <DateTime>] [-ComputerName <string[]>] [-EntryType <string[]>] [-Index <Int32[]>]
[-Message <string>] [-Newest <int>] [-Source<string[]>] [-UserName <string[]>] [<CommonParameters>]

Look at the synopsis – local or remote computers. Computername for local/remote machines. EntryType gives the type of entry. Thats about it.

PS> Get-Help Get-EventLog -Parameter EntryType

-EntryType <string[]>
    Gets only events with the specified entry type. Valid values are Error, Information, FailureAudit, SuccessAudit, and Warning. The default is all events.

    Required?                    false
    Position?                    named
    Default value                All events
    Accept pipeline input?       false
    Accept wildcard characters?  false

What does an entry look like?

PS> Get-EventLog -LogName Application | select -f 1 | Format-List


Index              : 83084
EntryType          : Information
InstanceId         : 1073872902
Message            : BBSvc has stopped.
Category           : (0)
CategoryNumber     : 0
ReplacementStrings : {BBSvc}
Source             : BBSvc
TimeGenerated      : 17/04/2012 18:00:17
TimeWritten        : 17/04/2012 18:00:17
UserName           :

 

We have an entry type so we can select on that and we have a source.  How can we can the total number of entries per source?

 

PS> Get-EventLog -LogName Application -EntryType Error | group Source

Count Name                      Group
----- ----                      -----
  166 SideBySide                {System.Diagnostics.EventLogEntry, System.Di
   27 Application Error         {System.Diagnostics.EventLogEntry, System.Di
    1 System Restore            {System.Diagnostics.EventLogEntry}
    2 Microsoft-Windows-Rest... {System.Diagnostics.EventLogEntry, System.Di
    3 VSS                       {System.Diagnostics.EventLogEntry, System.Di
   20 Application Hang          {System.Diagnostics.EventLogEntry, System.Di
    1 MsiInstaller              {System.Diagnostics.EventLogEntry}

 

All we need is the Count and the name so we can use the –NoElement parameter

PS> Get-EventLog -LogName Application -EntryType Error | group Source -NoElement

Count Name
----- ----
  166 SideBySide
   27 Application Error
    1 System Restore
    2 Microsoft-Windows-Rest...
    3 VSS
   20 Application Hang
    1 MsiInstaller

 

But  we want them in descending order – actually requirements state largest number of errors at the top of the list which we already have but we will show willing and actually sort the list Smile

PS> Get-EventLog -LogName Application -EntryType Error |
group Source -NoElement | sort Count -Descending

Count Name
----- ----
  166 SideBySide
   27 Application Error
   20 Application Hang
    3 VSS
    2 Microsoft-Windows-Rest...
    1 MsiInstaller
    1 System Restore

 

If you want to see the whole name

PS> Get-EventLog -LogName Application -EntryType Error | group Source -NoElement |
sort Count -Descending | Format-table Count, Name -AutoSize

Count Name
----- ----
  166 SideBySide
   27 Application Error
   20 Application Hang
    3 VSS
    2 Microsoft-Windows-RestartManager
    1 MsiInstaller
    1 System Restore

 

We haven’t shown how to access a remote machine

PS> Get-EventLog -LogName Application -EntryType Error -Computername $env:COMPUTERNAME |
group Source -NoElement | sort Count -Descending | Format-table Count, Name –AutoSize

saving to a file:

PS> Get-EventLog -LogName Application -EntryType Error -Computername $env:COMPUTERNAME |
group Source -NoElement | sort Count -Descending | Format-table Count, Name -AutoSize |
Out-File beg5.txt

is legitimate and gives you exactly what you see on screen – though object police will scream at you for using format-table so if you want to conform try

PS> Get-EventLog -LogName Application -EntryType Error -Computername $env:COMPUTERNAME |
group Source -NoElement | sort Count -Descending | Out-File beg5.txt

but long source names may be truncated

if you really want to demonstrate you know what you are doing

PS> Get-EventLog -LogName Application -EntryType Error -Computername $env:COMPUTERNAME |
group Source -NoElement | sort Count -Descending | Tee-Object -FilePath beg5.txt

tee-object writes to a file and passes along pipeline to finally display

don’t use Add-Content or Set-Content as as all you will get is a set of lines like this

Microsoft.PowerShell.Commands.GroupInfoNoElement

These cmdlets don’t resolve the objects to the data

The Get-WinEvent syntax would be

Get-WinEvent -ComputerName $env:COMPUTERNAME -FilterHashtable @{'LogName'='Application'; 'Level'=2}

which to my mind isn’t as simple as Get-EventLog.

And finally if you just can’t live without aliases – get-eventlog doesn’t have one.

Leave a Reply