The Road to Delphi

Delphi – Free Pascal – Oxygene

WMI Tasks using Delphi – Event Logs

11 Comments

How do I retrieve information about the Security event log?

Use the Win32_NTEventlogFile class.

const
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator : OLEVariant;
  FWMIService   : OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject   : OLEVariant;
  oEnum         : IEnumvariant;
  iValue        : LongWord;
begin;
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService   := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');
  FWbemObjectSet:= FWMIService.ExecQuery('SELECT MaxFileSize ,NumberOfRecords FROM Win32_NTEventlogFile Where LogFileName="Security"','WQL',wbemFlagForwardOnly);
  oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
  while oEnum.Next(1, FWbemObject, iValue) = 0 do
  begin
    Writeln(Format('Max File Size        %d',[Integer(FWbemObject.MaxFileSize)]));
    Writeln(Format('Number Of Records    %d',[Integer(FWbemObject.NumberOfRecords)]));
    Writeln;
    FWbemObject:=Unassigned;
  end;
end;

How do I back up an event log?

Use the Win32_NTEventlogFile class and the BackupEventLog method

const
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator : OLEVariant;
  FWMIService   : OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject   : OLEVariant;
  oEnum         : IEnumvariant;
  iValue        : LongWord;
begin;
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService   := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');
  FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_NTEventlogFile Where LogFileName="Application"','WQL',wbemFlagForwardOnly);
  oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
  if oEnum.Next(1, FWbemObject, iValue) = 0 then
  begin
    FWbemObject.BackupEventLog('c:\logs\backup.evt');
    FWbemObject:=Unassigned;
  end;
end;

How do I back up an event log more than once?

Ensure that the backup file has a unique name before using the Win32_NTEventlogFile and the BackupEventLog method. The operating system does not allow you to overwrite an existing backup file; you must either move the backup file or rename it before you can run the script again.

const
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator : OLEVariant;
  FWMIService   : OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject   : OLEVariant;
  oEnum         : IEnumvariant;
  iValue        : LongWord;
begin;
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService   := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');
  FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_NTEventlogFile Where LogFileName="Application"','WQL',wbemFlagForwardOnly);
  oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
  if oEnum.Next(1, FWbemObject, iValue) = 0 then
  begin
    FWbemObject.BackupEventLog(Format('c:\logs\backup_%s.evt',[FormatDateTime('hhnnsszzz',Now)]));
    FWbemObject.ClearEventLog();
    FWbemObject:=Unassigned;
  end;
end;

How do I determine the number of records in an event log?

Use the Win32_NTEventlogFile class and check the value of the NumberOfRecords property.

const
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator : OLEVariant;
  FWMIService   : OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject   : OLEVariant;
  oEnum         : IEnumvariant;
  iValue        : LongWord;
begin;
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService   := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');
  FWbemObjectSet:= FWMIService.ExecQuery('SELECT NumberOfRecords FROM Win32_NTEventlogFile Where LogFileName="Security"','WQL',wbemFlagForwardOnly);
  oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
  if oEnum.Next(1, FWbemObject, iValue) = 0 then
  begin
    Writeln(Format('Number Of Records    %d',[Integer(FWbemObject.NumberOfRecords)]));
    Writeln;
    FWbemObject:=Unassigned;
  end;
end;

How do I clear my event logs?

Use the Win32_NTEventlogFile class and the ClearEventLog method.

const
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator : OLEVariant;
  FWMIService   : OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject   : OLEVariant;
  oEnum         : IEnumvariant;
  iValue        : LongWord;
begin;
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService   := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');
  FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_NTEventlogFile Where LogFileName="Application"','WQL',wbemFlagForwardOnly);
  oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
  if oEnum.Next(1, FWbemObject, iValue) = 0 then
  begin
    FWbemObject.ClearEventLog();
    FWbemObject:=Unassigned;
  end;
end;

How do I read events from the event logs?

Use the Win32_NTLogEvent class.

const
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator : OLEVariant;
  FWMIService   : OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject   : OLEVariant;
  oEnum         : IEnumvariant;
  iValue        : LongWord;
begin;
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService   := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');
  FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_NTLogEvent  Where Logfile="System"','WQL',wbemFlagForwardOnly);
  oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
  while oEnum.Next(1, FWbemObject, iValue) = 0 do
  begin
    Writeln(Format('Category          %s',[String(FWbemObject.Category)]));
    Writeln(Format('Computer Name     %s',[String(FWbemObject.ComputerName)]));
    Writeln(Format('EventCode         %d',[Integer(FWbemObject.EventCode)]));
    Writeln(Format('Message           %s',[String(FWbemObject.Message)]));
    Writeln(Format('RecordNumber      %d',[Integer(FWbemObject.RecordNumber)]));
    FWbemObject:=Unassigned;
  end;
end;

This post is based in the MSDN entry WMI Tasks: Event Logs

Author: Rodrigo

Just another Delphi guy.

11 thoughts on “WMI Tasks using Delphi – Event Logs

  1. Interesting, but it looks much more complex than using the eventlog API directly. Probably useful if you have to read the eventlog from vbscript.

  2. Luigi, does the Event Log API allow you to query the logs of remote machines?

  3. Thank you very much for the code.

    in the part “How do I read events from the event logs?” I have noticed that it works only for Event Logs of kind Application and System. If one needs the Security Event Logs it will not return anything.
    As far as i have read this has to do with setting the impersonation level to “impersonate.” Such code I have found only in VB.
    Can anyone help with a delphi variant

    thanks and regards
    Altin

  4. Thank you very much for your answer Rodrigo.
    I have done that, set FWMIService.Security_.ImpersonationLevel = 3, as you suggest, but no result.
    have you tested the code in discussion with event log Security ? does it works on your side ?

    regards
    Altin

  5. Hello Rodrigo, I have a short question. I tried your Code and it’s very easy to use, but I still have one problem. I want to recognize new events so I can read them. My first thought was to check every XX seconds the number of records. If new events appear I would like to jump to the oldst of the new events, add it into an array, go to the next one, read it and so on until the last event was readed. But I haven’t found a way to navigate through the eventlog. Have you got an Idea for me?

    Thanks,
    LuMa

  6. Pingback: How can i read WMI parameters "Data" and "InsertionStrings"? | Technology & Programming

Leave a comment