C# 如何使用WMI导出特定源的Windows事件日志?
我试图使用WMI类导出Windows事件日志的C# 如何使用WMI导出特定源的Windows事件日志?,c#,.net,wmi,event-log,C#,.net,Wmi,Event Log,我试图使用WMI类导出Windows事件日志的应用程序分支,但仅对特定源进行筛选。(否则,日志包含太多不必要的信息。) 例如,我需要导出包含MSSQL$SQLSRVR2012的所有记录: 我这样做: using System.Management; static void Main(string[] args) { BackupEventLogFilterBySource("Application", "MSSQL$SQLSRVR2012", @"C:\Use
应用程序
分支,但仅对特定源进行筛选。(否则,日志包含太多不必要的信息。)
例如,我需要导出包含MSSQL$SQLSRVR2012
的所有记录:
我这样做:
using System.Management;
static void Main(string[] args)
{
BackupEventLogFilterBySource("Application", "MSSQL$SQLSRVR2012", @"C:\Users\User\Desktop\exp.evtx");
}
public static void BackupEventLogFilterBySource(String logName, String applicationName, String targetFile)
{
ManagementScope scope = new ManagementScope(@"\\.\root\cimv2");
scope.Options.EnablePrivileges = true;
scope.Options.Impersonation = ImpersonationLevel.Impersonate;
ObjectQuery query = new ObjectQuery(
String.Format("Select * from Win32_NTEventLogFile Where LogFileName='{0}' And Sources='{1}'",
logName, applicationName)
);
using (ManagementObjectSearcher search =
new ManagementObjectSearcher(scope, query))
{
foreach (ManagementObject o in search.Get())
{
ManagementBaseObject inParams = o.GetMethodParameters("BackupEventlog");
inParams["ArchiveFileName"] = targetFile;
ManagementBaseObject outParams = o.InvokeMethod("BackupEventLog", inParams, null);
var res = outParams.Properties["ReturnValue"].Value;
Console.Write("result=" + res + "\n");
}
}
}
但该查询失败,出现以下异常:
“System.Management.ManagementException”类型的未处理异常
发生在System.Management.dll中
其他信息:无效查询
那么我做错了什么呢?用于标识
源代码的内部名称可能与计算机管理UI中显示的名称不同。
例如,源Winlogon
,在内部被引用为Microsoft Windows Winlogon
另外,Sources
参数也有问题,因为它是一个数组。
此修改的方法使用Win32\u NTLogEvent
而不是Win32\u NTEventLogFile
我认为它更直接地指向目标。
由于我提到的原因,查询使用像“%parameter%”这样的来过滤源代码。但是,可以使用原始方法通过LogFileName
过滤器提取所有源名称,并分析sources{}
数组的内容
从日志源文件提取的值存储在列表中。
您可以使用它的属性创建一个类似于您在事件查看器中看到的报告。
注意:可以使用
公共类WinLogEvent
{
公共字符串ComputerName{get;set;}
公共字符串日志名{get;set;}
公共字符串消息{get;set;}
公共字符串源{get;set;}
公共UInt16事件代码{get;set;}
公共uint事件标识符{get;set;}
公共字符串事件类型{get;set;}
公共uint记录编号{get;set;}
public DateTime?TimeGenerated{get;set;}
公共日期时间?时间记录{get;set;}
公共字节[]数据{get;set;}
公共字符串[]插入字符串{get;set;}
}
私有静态枚举选项GetEnumerationOptions(布尔深度扫描)
{
var mOptions=新枚举选项()
{
Rewindable=false,//仅向前查询=>无缓存
return立即=true,//伪异步结果
DirectRead=true,
枚举深度=深度扫描
};
返回运动;
}
私有静态连接选项GetConnectionOptions(字符串用户名、字符串密码、字符串域)
{
var connpoptions=新连接选项()
{
EnablePrivileges=true,
超时=ManagementOptions.InfiniteTimeout,
身份验证=AuthenticationLevel.PacketPrivacy,
模拟=模拟级别。默认值,
用户名=用户名,
密码=密码,
//Authority=“NTLMDOMAIN:[域]”
Authority=!string.IsNullOrEmpty(域)?$“NTLMDOMAIN:{Domain}”:string.Empty
};
返回选项;
}
公共静态列表BackupEventLogFilterBySource(字符串logName,字符串sourceName)
{
List logEvents=新列表();
var connpoptions=GetConnectionOptions(null,null,null);
var options=GetEnumerationOptions(false);
var scope=new ManagementScope(@“\\”+Environment.MachineName+@“\root\CIMV2”,connOptions);
scope.Connect();
var query=new SelectQuery(“从Win32\u NTLogEvent中选择*);
query.Condition=$“Logfile='{logName}'和SourceName类似'{SourceName}%'”;
使用(ManagementObjectSearcher-moSearch=新的ManagementObjectSearcher(范围、查询、选项))
{
foreach(moSearch.Get()中的ManagementObject事件日志)
{
ManagementBaseObject inParams=eventLog.GetMethodParameters(“BackupEventlog”);
inParams[“ArchiveFileName”]=@“D:\exp.evtx”;
ManagementBaseObject outParams=eventLog.InvokeMethod(“BackupEventLog”,inParams,null);
var res=outParams.Properties[“ReturnValue”].Value;
添加(新的WinLogEvent
{
ComputerName=eventLog.GetPropertyValue(“ComputerName”)?.ToString(),
LogName=eventLog.GetPropertyValue(“日志文件”)?.ToString(),
Source=eventLog.GetPropertyValue(“SourceName”)?.ToString(),
EventCode=(UInt16?)eventLog.GetPropertyValue(“EventCode”)??0,
EventIdentifier=(uint?)eventLog.GetPropertyValue(“EventIdentifier”)??0,
EventType=eventLog.GetPropertyValue(“类型”)?.ToString(),
RecordNumber=(uint?)eventLog.GetPropertyValue(“RecordNumber”)??0,
TimeGenerated=ManagementDateTimeConverter.ToDateTime(eventLog.GetPropertyValue(“TimeGenerated”)?.ToString(),
TimeLogged=ManagementDateTimeConverter.ToDateTime(eventLog.GetPropertyValue(“TimeWrited”)?.ToString(),
Message=eventLog.GetPropertyValue(“Message”)?.ToString(),
InsertionString=(string[])eventLog.GetPropertyValue(“InsertionString”)??空,
数据=(字节[])eventLog.GetPropertyValue(“数据”)??空,
});
inParams.Dispose();
outParams.Dispose();
}
}
返回日志事件;
}//BackupEventLogFilterBySource
在查询中,必须将源
替换为源名称
。为了获得正确的WMI查询,请使用wbemtest
,它将准确地让您知道要查询的字段。我不确定,但是,如果您阅读了此文档:它说Sources
是一个字符串数组type@FaizanRabbani:是的,我也看到了。虽然我不知道那是什么意思?这并不是真的让人感到惊讶
public class WinLogEvent
{
public string ComputerName { get; set; }
public string LogName { get; set; }
public string Message { get; set; }
public string Source { get; set; }
public UInt16 EventCode { get; set; }
public uint EventIdentifier { get; set; }
public string EventType { get; set; }
public uint RecordNumber { get; set; }
public DateTime? TimeGenerated { get; set; }
public DateTime? TimeLogged { get; set; }
public byte[] Data { get; set; }
public string[] InsertionStrings { get; set; }
}
private static EnumerationOptions GetEnumerationOptions(bool deepScan)
{
var mOptions = new EnumerationOptions()
{
Rewindable = false, //Forward only query => no caching
ReturnImmediately = true, //Pseudo-async result
DirectRead = true,
EnumerateDeep = deepScan
};
return mOptions;
}
private static ConnectionOptions GetConnectionOptions(string UserName, string Password, string Domain)
{
var connOptions = new ConnectionOptions()
{
EnablePrivileges = true,
Timeout = ManagementOptions.InfiniteTimeout,
Authentication = AuthenticationLevel.PacketPrivacy,
Impersonation = ImpersonationLevel.Default,
Username = UserName,
Password = Password,
//Authority = "NTLMDOMAIN:[domain]"
Authority = !string.IsNullOrEmpty(Domain) ? $"NTLMDOMAIN:{Domain}" : string.Empty
};
return connOptions;
}
public static List<WinLogEvent> BackupEventLogFilterBySource(string logName, string sourceName)
{
List<WinLogEvent> logEvents = new List<WinLogEvent>();
var connOptions = GetConnectionOptions(null, null, null);
var options = GetEnumerationOptions(false);
var scope = new ManagementScope(@"\\" + Environment.MachineName + @"\root\CIMV2", connOptions);
scope.Connect();
var query = new SelectQuery("SELECT * FROM Win32_NTLogEvent");
query.Condition = $"Logfile='{logName}' AND SourceName LIKE '%{sourceName}%'";
using (ManagementObjectSearcher moSearch = new ManagementObjectSearcher(scope, query, options))
{
foreach (ManagementObject eventLog in moSearch.Get())
{
ManagementBaseObject inParams = eventLog.GetMethodParameters("BackupEventlog");
inParams["ArchiveFileName"] = @"D:\exp.evtx";
ManagementBaseObject outParams = eventLog.InvokeMethod("BackupEventLog", inParams, null);
var res = outParams.Properties["ReturnValue"].Value;
logEvents.Add(new WinLogEvent
{
ComputerName = eventLog.GetPropertyValue("ComputerName")?.ToString(),
LogName = eventLog.GetPropertyValue("Logfile")?.ToString(),
Source = eventLog.GetPropertyValue("SourceName")?.ToString(),
EventCode = (UInt16?)eventLog.GetPropertyValue("EventCode") ?? 0,
EventIdentifier = (uint?)eventLog.GetPropertyValue("EventIdentifier") ?? 0,
EventType = eventLog.GetPropertyValue("Type")?.ToString(),
RecordNumber = (uint?)eventLog.GetPropertyValue("RecordNumber") ?? 0,
TimeGenerated = ManagementDateTimeConverter.ToDateTime(eventLog.GetPropertyValue("TimeGenerated")?.ToString()),
TimeLogged = ManagementDateTimeConverter.ToDateTime(eventLog.GetPropertyValue("TimeWritten")?.ToString()),
Message = eventLog.GetPropertyValue("Message")?.ToString(),
InsertionStrings = (string[])eventLog.GetPropertyValue("InsertionStrings") ?? null,
Data = (byte[])eventLog.GetPropertyValue("Data") ?? null,
});
inParams.Dispose();
outParams.Dispose();
}
}
return logEvents;
} //BackupEventLogFilterBySource