Jump to content

Problems and questions with Event Viewer.


Go to solution Solved by TheXman,

Recommended Posts

Posted

Good evening everyone,

After a lot of searching and looking at the links below, I couldn't find a native solution or a function that could solve my problem.

Really AutoIt and the Event Viewer Function (with its additional ones), is it not possible to read the subfolders and filter them?

Examples: Read the events in:

1 - Microsoft-Windows-WLAN-AutoConfig/Operational
1.1 - Return filter 14001 or 11005
1.1.1 - View the last 50 filter records above the same log.

As I couldn't find any examples or help on the subject, I couldn't find a way to start the code.

The question remains:

Is it still not possible?
If possible, could someone give me a direction to start developing?

PS. I found it only with "wevtutil" in CMD.

Posted (edited)

Yes, it is possible.  You could get the information in many ways.  You could use a WMI query, a wmic console command query, or a PowerShell command to name a few.

In this particular case, if you want to use WMI or wmic, then you must make sure that the associated registry key exists before doing the query.  When you look at your Event Viewer, under "Applications and Services Logs", you probably do not see an entry for "Microsoft-Windows-WLAN-AutoConfig/Operational".  When you create the associated key, you will see it in the list and be able to query it as you normally would using WMI or wmic.

Event Viewer image after registry key is created:

image.thumb.png.1e54839252dcaea775e3e003cd395637.png

image.png.ac30de73d144a7e44766b6150520ccfe.png

The example script below checks to see if the registry entry key exists.  If it doesn't, then it creates it.  The script then continues on to do a regular WMI query of that event log, puts the result into an array, and then trims that array to the last 50 entries.

#AutoIt3Wrapper_AU3Check_Parameters=-w 3 -w 4 -w 5 -w 6 -d

#RequireAdmin

#include <Constants.au3>
#include <Array.au3>


wmi_example()

Func wmi_example()
    Const $MAX_EVENTS = 50
    Const $LOGFILE    = "Microsoft-Windows-WLAN-AutoConfig/Operational"

    Local $oComErr, $oWmi, $oInstances
    Local $aEvents[0][4]


    ;Set up local COM error handler
    $oComErr = ObjEvent("AutoIt.Error", com_error_handler)
    #forceref $oComErr

    ;If registry key doesn't exist, then create it
    RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\" & $LOGFILE, "")
    Switch @error
        Case 1 ;Registry key does not exist
            ;Create reg key
            RegWrite("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\" & $LOGFILE)
            ConsoleWrite("Registry key created." & @CRLF)

        Case -1 ;Default value not set
            ;Continue - this is okay

        Case Else
            Exit MsgBox($MB_ICONERROR, "RegRead Error", "RegRead failed with @error = " & @error)
    EndSwitch

    ;Get WMI object
    $oWmi = ObjGet("winmgmts:")
    If Not IsObj($oWmi) Then Exit MsgBox($MB_ICONERROR, "ERROR", "Unable to create WMI object")

    ;Execute WMI query to get instances of interest
    $oInstances = $oWmi.ExecQuery( _
        'SELECT TimeGenerated, EventIdentifier, Type, Message ' & _
        'FROM   Win32_NTLogEvent ' & _
        'WHERE  LogFile="' & $LOGFILE & '" ' & _
        '       And (EventIdentifier = 14001 or EventIdentifier = 11005)' _
        )
    If $oInstances.Count = 0 Then Exit MsgBox($MB_ICONWARNING,"Warning","No instances found.")

    ;For each instance
    For $oInstance in $oInstances
        With $oInstance
            ;Add instance values to the array
            _ArrayAdd($aEvents, .TimeGenerated & "|" & .EventIdentifier & "|" & .Type & "|" & .Message, 0, "|", "~~~")
        EndWith
    Next

    ;Sort array by timestamp and trim it to last $MAX_EVENTS entries
    _ArraySort($aEvents)
    If UBound($aEvents) > $MAX_EVENTS Then _ArrayDelete($aEvents, StringFormat("0-%i", UBound($aEvents) - $MAX_EVENTS - 1))

    ;Display result
    _ArrayDisplay($aEvents, "Events", "", 0, Default, "Time|Event ID|Type|Message")

EndFunc

Func com_error_handler($oError)
    With $oError
        ConsoleWrite(@CRLF)
        ConsoleWrite("COM ERROR:" & @CRLF)
        ConsoleWrite("- Error Number........... " & "0x" & Hex(.number) & @CRLF)
        ConsoleWrite("- Error WinDescription... " & StringStripWS(.windescription, $STR_STRIPTRAILING) & @CRLF)
        ConsoleWrite("- Error Description...... " & StringStripWS(.description   , $STR_STRIPTRAILING) & @CRLF)
        ConsoleWrite("- Error ScriptLine....... " & .scriptline & @CRLF)
        ConsoleWrite("- Error RetCode.......... " & "0x" & Hex(.retcode) & @CRLF)
    EndWith
    Exit
EndFunc

Example array created by the script above:

image.png.2a186f3d86aea13cb6ff5cda44230abc.png

 

Edited by TheXman
Posted
18 hours ago, TheXman said:

Yes, it is possible.  You could get the information in many ways.  You could use a WMI query, a wmic console command query, or a PowerShell command to name a few.

In this particular case, if you want to use WMI or wmic, then you must make sure that the associated registry key exists before doing the query.  When you look at your Event Viewer, under "Applications and Services Logs", you probably do not see an entry for "Microsoft-Windows-WLAN-AutoConfig/Operational".  When you create the associated key, you will see it in the list and be able to query it as you normally would using WMI or wmic.

Event Viewer image after registry key is created:

image.thumb.png.1e54839252dcaea775e3e003cd395637.png

image.png.ac30de73d144a7e44766b6150520ccfe.png

The example script below checks to see if the registry entry key exists.  If it doesn't, then it creates it.  The script then continues on to do a regular WMI query of that event log, puts the result into an array, and then trims that array to the last 50 entries.

#AutoIt3Wrapper_AU3Check_Parameters=-w 3 -w 4 -w 5 -w 6 -d

#RequireAdmin

#include <Constants.au3>
#include <Array.au3>


wmi_example()

Func wmi_example()
    Const $MAX_EVENTS = 50
    Const $LOGFILE    = "Microsoft-Windows-WLAN-AutoConfig/Operational"

    Local $oComErr, $oWmi, $oInstances
    Local $aEvents[0][4]


    ;Set up local COM error handler
    $oComErr = ObjEvent("AutoIt.Error", com_error_handler)
    #forceref $oComErr

    ;If registry key doesn't exist, then create it
    RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\" & $LOGFILE, "")
    Switch @error
        Case 1 ;Registry key does not exist
            ;Create reg key
            RegWrite("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\" & $LOGFILE)
            ConsoleWrite("Registry key created." & @CRLF)

        Case -1 ;Default value not set
            ;Continue - this is okay

        Case Else
            Exit MsgBox($MB_ICONERROR, "RegRead Error", "RegRead failed with @error = " & @error)
    EndSwitch

    ;Get WMI object
    $oWmi = ObjGet("winmgmts:")
    If Not IsObj($oWmi) Then Exit MsgBox($MB_ICONERROR, "ERROR", "Unable to create WMI object")

    ;Execute WMI query to get instances of interest
    $oInstances = $oWmi.ExecQuery( _
        'SELECT TimeGenerated, EventIdentifier, Type, Message ' & _
        'FROM   Win32_NTLogEvent ' & _
        'WHERE  LogFile="' & $LOGFILE & '" ' & _
        '       And (EventIdentifier = 14001 or EventIdentifier = 11005)' _
        )
    If $oInstances.Count = 0 Then Exit MsgBox($MB_ICONWARNING,"Warning","No instances found.")

    ;For each instance
    For $oInstance in $oInstances
        With $oInstance
            ;Add instance values to the array
            _ArrayAdd($aEvents, .TimeGenerated & "|" & .EventIdentifier & "|" & .Type & "|" & .Message, 0, "|", "~~~")
        EndWith
    Next

    ;Sort array by timestamp and trim it to last $MAX_EVENTS entries
    _ArraySort($aEvents)
    If UBound($aEvents) > $MAX_EVENTS Then _ArrayDelete($aEvents, StringFormat("0-%i", UBound($aEvents) - $MAX_EVENTS - 1))

    ;Display result
    _ArrayDisplay($aEvents, "Events", "", 0, Default, "Time|Event ID|Type|Message")

EndFunc

Func com_error_handler($oError)
    With $oError
        ConsoleWrite(@CRLF)
        ConsoleWrite("COM ERROR:" & @CRLF)
        ConsoleWrite("- Error Number........... " & "0x" & Hex(.number) & @CRLF)
        ConsoleWrite("- Error WinDescription... " & StringStripWS(.windescription, $STR_STRIPTRAILING) & @CRLF)
        ConsoleWrite("- Error Description...... " & StringStripWS(.description   , $STR_STRIPTRAILING) & @CRLF)
        ConsoleWrite("- Error ScriptLine....... " & .scriptline & @CRLF)
        ConsoleWrite("- Error RetCode.......... " & "0x" & Hex(.retcode) & @CRLF)
    EndWith
    Exit
EndFunc

Example array created by the script above:

image.png.2a186f3d86aea13cb6ff5cda44230abc.png

 

Thank you so much @TheXman

I have been in the development business for a very short time and in AutoIt less than 1 year.
I have learned a lot from this forum. Almost all of my knowledge base is from this site and people willing to teach. One day I hope to get my turn to return to this forum.

Now I'm going to study more what you explained to me and try to turn to new consultations and other developments in the same direction.

  • Solution
Posted (edited)
5 hours ago, ARPFre said:

Thank you so much

You're welcome. 😃

 

FYI:
In the future, there's no need to quote a FULL post in your reply.  You can just quote the relevant part(s), if you feel so inclined, like above. ;)

Edited by TheXman

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...