You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中拼接Event Log提取变量后控制台输出空白问题求助

问题

编写C#脚本从Windows安全日志的4625(登录失败)事件中提取时间、IP地址、账户名与账户域,单独输出各变量时控制台显示正常,但拼接成字符串后,输出内容缺失时间与IP信息。尝试过对变量调用ToString()方法、使用字符串插值,均未解决问题。

相关代码

using System;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;

class Program
{
    static void Main()
    {
        string GetIP(string input)
        {
            Regex regex = new Regex(@"Source Network Address:.*");
            Match match = regex.Match(input);
            if (match.Success)
            {
                string ipAddress = Regex.Replace(match.Value, @"Source Network Address:\s*", "");
                return ipAddress;
            }
            else
            {
                return "No match found.";
            }
        }

        string GetAcc(string input)
        {
            Regex regexAccountName = new Regex(@"Account Name:\s*(\S+)");
            MatchCollection matches = regexAccountName.Matches(input);
            if (matches.Count >= 2)
            {
                string accountName = matches[1].Groups[1].Value;
                return accountName;
            }
            else
            {
                return "No match found.";
            }
        }

        string GetDomain(string input)
        {
            Regex regexAccountName = new Regex(@"Account Domain:\s*(\S+)");
            MatchCollection matches = regexAccountName.Matches(input);
            if (matches.Count >= 2)
            {
                string accountName = matches[1].Groups[1].Value;
                return accountName;
            }
            else
            {
                return "No match found.";
            }
        }

        Console.WriteLine("Date/Time,IP Address,Account Name,Account Domain");
        int targetEventId = 4625;
        string logName = "Security";
        EventLog eventLog = new EventLog(logName);

        foreach (EventLogEntry entry in eventLog.Entries)
        {
            if (entry.InstanceId == targetEventId)
            {
                DateTime Time = Convert.ToDateTime(entry.TimeGenerated);
                Console.WriteLine(Time);
                string message = entry.Message;
                string ip = GetIP(message);
                Console.WriteLine(ip);
                string acc = GetAcc(message);
                Console.WriteLine(acc);
                string domain = GetDomain(message);
                Console.WriteLine(domain);

                string csvOutput = Time + "," + ip + "," + acc + "," + domain;
                Console.WriteLine(csvOutput);
            }
        }
        eventLog.Close();
        Console.WriteLine("End of logs. Press any key to exit.");
        Console.ReadKey();
    }
}

场景说明

  • 输入:Windows安全日志中ID为4625的登录失败事件详细内容
  • 实际输出:拼接后的字符串缺失时间与IP信息
  • 预期输出:完整CSV格式内容,例如:9/26/2023 10:39:53 AM,192.168.1.198,abc@def.ghi,MicrosoftAccount

解决方案

问题根源是提取的IP字符串中包含隐藏的回车/换行控制字符,控制台单独输出时会自动换行,但拼接后这些控制字符会覆盖前面的时间内容(类似终端的\r光标回退)。同时优化正则逻辑,避免不必要的字符串处理:

修复步骤

  1. 清理提取字符串中的控制字符:对提取的IP、账户名、域字符串调用Trim(),或显式移除\r、\n
  2. 优化IP提取正则:直接捕获IP地址,减少字符串替换操作,避免引入控制字符
  3. 明确格式化DateTime:避免默认格式可能带来的问题

修改后的代码

using System;
using System.Diagnostics;
using System.Text.RegularExpressions;

class Program
{
    static void Main()
    {
        string GetIP(string input)
        {
            // 直接捕获IP地址,避免匹配整行带来的换行符
            Regex regex = new Regex(@"Source Network Address:\s*(\S+)");
            Match match = regex.Match(input);
            if (match.Success)
            {
                // 清理可能的控制字符
                return match.Groups[1].Value.Trim().Replace("\r", "").Replace("\n", "");
            }
            else
            {
                return "No match found.";
            }
        }

        string GetAcc(string input)
        {
            Regex regexAccountName = new Regex(@"Account Name:\s*(\S+)");
            MatchCollection matches = regexAccountName.Matches(input);
            if (matches.Count >= 2)
            {
                return matches[1].Groups[1].Value.Trim().Replace("\r", "").Replace("\n", "");
            }
            else
            {
                return "No match found.";
            }
        }

        string GetDomain(string input)
        {
            Regex regexAccountName = new Regex(@"Account Domain:\s*(\S+)");
            MatchCollection matches = regexAccountName.Matches(input);
            if (matches.Count >= 2)
            {
                return matches[1].Groups[1].Value.Trim().Replace("\r", "").Replace("\n", "");
            }
            else
            {
                return "No match found.";
            }
        }

        Console.WriteLine("Date/Time,IP Address,Account Name,Account Domain");
        int targetEventId = 4625;
        string logName = "Security";
        EventLog eventLog = new EventLog(logName);

        foreach (EventLogEntry entry in eventLog.Entries)
        {
            if (entry.InstanceId == targetEventId)
            {
                DateTime time = entry.TimeGenerated; // 无需Convert,TimeGenerated本身就是DateTime
                Console.WriteLine(time);
                string message = entry.Message;
                string ip = GetIP(message);
                Console.WriteLine(ip);
                string acc = GetAcc(message);
                Console.WriteLine(acc);
                string domain = GetDomain(message);
                Console.WriteLine(domain);

                // 使用字符串插值,并明确格式化时间
                string csvOutput = $"{time:G},{ip},{acc},{domain}";
                Console.WriteLine(csvOutput);
            }
        }
        eventLog.Close();
        Console.WriteLine("End of logs. Press any key to exit.");
        Console.ReadKey();
    }
}

关键修改点

  • IP提取正则改为捕获组(\S+),直接获取IP,避免匹配整行引入换行符
  • 所有提取的字符串都调用Trim()并移除\r、\n,彻底清理控制字符
  • 直接使用entry.TimeGenerated,无需额外转换
  • 字符串插值时明确指定时间格式G(常规日期时间格式)

内容的提问来源于stack exchange,提问作者TWB503

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 01:15:24