10

I want to read the Event Log on a remote computer to check for errors during testing. Here's some relevant code:

public bool CheckEventLogs(DateTime start)
{
  EventLog myEventLog = new EventLog("CustomLog", "ServerName");
  bool errorFound = false;
  foreach (EventLogEntry entry in myEventLog.Entries)
  {
    if (entry.EntryType == EventLogEntryType.Error && entry.TimeGenerated >= start)
    {
       Console.WriteLine("Error in Event Log:\n" + entry.Message + "\n");
       errorFound = true;
    }
  }
  return errorFound;
}

Currently, this code throws an exception (Attempted to perform an unauthorized operation). According to MSDN, I need EventLogPermission, but I have been struggling to find any examples of how to use this permission. Does anyone have an example of how to do this?

Edit: Response to Comments

Thank you all for the comments - here is the additional information requested:

The exception is thrown from the foreach statement. Specifically, when stepping through the code it thrown in the step after when in is highlighted. It seems that I was able to create the event log object but I'm not able to access the entries in the event log.

My account does not have permission to read the event log on the target system, but I have credentials for an account which does. When connecting manually through the event viewer there is an option to connect as another user. After doing this manually, then my code ran without a problem. However, I cannot rely doing it manually every time this program runs. What I need is a way to connect as another user programmaticly. I thought that the EventLogPermission would be the way to do that, but maybe there is another way. If anyone knows how to connect to a remote log as a different user in C#, that would be exactly what I was looking for.

Brian
  • 1,201
  • 2
  • 14
  • 26
  • 1
    Which line throws the exception? The MSDN article only says that you need permission to write -- it doesn't say anything about reading. – Gabe Mar 15 '11 at 14:31
  • 1
    Does your user account have permission to read the event log on the remote machine? Open Event Viewer and try connecting to the remote computer from your machine to check. – Stefan Dragnev Mar 15 '11 at 14:56
  • I just try your code and get logs from remote server. Everything works fine. – Polaris Mar 15 '11 at 14:59
  • Thank you @Gabe, @Stefan, and @Polaris for your comments. I've updated the question with the additional information. – Brian Mar 15 '11 at 17:35

2 Answers2

7

WMI is incredibly useful for this, a snippet like

SELECT Logfile,TimeGenerated,Type,SourceName,Message FROM Win32_NTLogEvent

Would allow you to query the logs. This utility from MS will allow you to explore WMI and will even build the .net code to invoke the queries.

Another benefit to this is that its going to get all the events and bring them local to the application where you can parse them at your leisure. Iterating the events in the way you are doing now is prone to failure if the connection is broken while you are processing (incidentally this is the same method that is typically employed with database access).

StingyJack
  • 19,041
  • 10
  • 63
  • 122
4

Thanks to everyone who provided comments on this question. Once I realized that the permissions might not be a part of .NET but part of Windows and the Event Viewer itself, I had some new direction for my own investigations.

It looks like a "net use" command was all that was needed to establish the connection between my local computer and the remote computer. When calling "net use" before using the code I posted in the question, things worked beautifully. It is simple enough to call that from the code before reading from the event log.

Thanks again for your help!

Brian
  • 1,201
  • 2
  • 14
  • 26
  • I think the original code I posted in the question had worked after I ran a "net use" command to establish the connection between my local computer and the remote computer. – Brian Sep 10 '12 at 11:45
  • Could you please show us how did you use `net use` from your code? I'm having a hard time finding this. – snippetkid Jun 17 '16 at 14:01
  • Our code uses some internal class libraries that aren't easy to share, but basically we use .NET's Directory.Exists to check if we can access a shared directory on the remote server. Directory.Exists returns false, then we use .NET's Process class to execute net.exe (we find the location of net.exe using Environment.SystemDirectory). – Brian Jun 20 '16 at 15:58