How to connect to a specific nested event log in a C# program?

72 views Asked by At

I'm writing a C# program that looks through the Windows event logs for remote desktop login attempts, then reports the logins with a csv of the time, IP addresses, username and domain. I can make it successfully read failed login attempts via the 'Security' log on event 4625, but I would like to make it be able to read successful login attempts, which are logged as event 1149 under 'Applications & Services logs -> Microsoft -> Windows -> terminalservices-remoteconnectionmanager -> Operational'. I've tried going to the event viewer to get the name of 'Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational', but it says it can't find the log. Here's the function I'm using to check:

using System.Diagnostics.Eventing.Reader;
(...)

private void CheckEventLog()
{
    if (exportPath == null)
    {
        // Program exports result as a CSV file, this shows an error if an export path is not specified
        DialogResult errorBox = MessageBox.Show("Please input an export path.", "Export error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return;
    }
    if (compInput.Text == "")
    {
        // For connecting to another computers logs; commented out because not working
        // Normally this selects the executing computers name if nothing is inputted
        // comp = Convert.ToString(System.Environment.MachineName);
    }
    else
    {
        comp = Convert.ToString(System.Environment.MachineName); // Same as above, but moved here so it always runs while the net function is disabled
        // comp = compInput.ToString(); // This takes the computer name input from the box (if we were using that function)
        username = usrImp.ToString();
        password = pasImp.ToString();
        SecureString securePassword = new SecureString();
        // ^^ those 3 lines are also for if using net
        foreach (char c in password)
        {
            securePassword.AppendChar(c);
        }
        // Normally there would be a } here, but since net is disabled AND there's warning text in compInput, we need the whole function to operate in the else statement
        // Time to connect to the event log...
        EventLogSession session = new EventLogSession(
            comp, // On <- this computer (while net is disabled, on local computer)
            username, // With this username
            null, // On this domain (disabled)
            securePassword, // With this password
            SessionAuthentication.Default);
    }
    string FilePath = Convert.ToString(exportPath.Text);
    // Creating the header for the CSV output
    string csvHeader = "Date/Time,IP Address,Account Name,Account Domain";
    var csv = new StringBuilder();
    csv.AppendLine(csvHeader);
    // Check the event log, logChoice is the input of the log input TextBox (My two examples are 'Security' [working] and 'Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational' [not working])
    EventLog eventLog = new EventLog(logChoice, comp);
    try
    {
        foreach (EventLogEntry entry in eventLog.Entries) // For each entry in the event log, check to see if the event number matches the one we're searching for 
        {
            if (entry.InstanceId.ToString() == eventChoice)
            {
                // Console lines commented out, ready for use when debugging
                // Console.WriteLine($"Event ID: {entry.InstanceId}");
                // Console.WriteLine($"Time: {entry.TimeGenerated}");
                DateTime Time = Convert.ToDateTime(entry.TimeGenerated);
                // Console.WriteLine(Time);
                // Console.WriteLine($"Message: {entry.Message}");
                string message = entry.Message;
                string ip = GetIP(message); // GetIP is a regex function to get extract an IP address from the event
                // Console.WriteLine(ip);
                string acc = GetAcc(message); // GetAcc is another regex function to get the account name attempting to log in 
                // Console.WriteLine(acc);
                string domain = GetDomain(message); // Same as other two but for domain
                // Console.WriteLine(domain);
                string csvOutput = Time + "," + ip + "," + acc + "," + domain; // Formats the time, ip, account, and domain into a CSV string
                Console.WriteLine(csvOutput);
                csv.AppendLine(csvOutput.ToString());
            }
        }
        eventLog.Close();
        File.WriteAllText(FilePath, csv.ToString()); // Write out the csv file
        csvOUT = csv.ToString();
    }
    // Error handling
    catch (IOException ex)
    {
        DialogResult result = MessageBox.Show($"Error: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    catch (InvalidOperationException IO)
    {
        DialogResult result = MessageBox.Show($"Error: {IO.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    return;
}

This is the error precisely: A screenshot of my error

I've tried removing the "/operational", replacing the dashes with slashes and vise versa, adding the "Applications & services", etc.

Thanks in advance. :)

0

There are 0 answers