还有另一个名为 System.Diagnostics.Eventing.Reader 的 .NET 命名空间,其中包含更多 .NET 类,允许您检索有关 Windows 事件跟踪 (ETW) 提供程序和在 Windows 操作系统中注册的事件日志的信息。大多数这些类型在 .NET Global Assembly Cache (GAC) 的 System.Core.dll .NET 程序集中定义。
例如,您可以执行以下操作(以及更多):
- 找出计算机上安装的 ETW 提供程序的名称
- 发现计算机上存在的 ETW 日志名称的完整列表
- 枚举与 ETW 提供程序相关的元数据
- 导出事件日志数据
ETW 提供者名称
ETW 的核心功能之一是获取安装在给定系统上的 ETW 提供程序列表。您可以使用 System.Diagnostics.Eventing.Reader 命名空间中的 .NET Framework 类型轻松检索此信息。恰好有一个名为EventLogSession 的.NET 类,在这个类上有一个名为GlobalSession 的静态属性,它会自动检索到本地计算机上事件日志服务的会话/连接。如有必要,您也可以使用EventLogSession 类的构造函数之一连接到远程计算机。
检索到EventLogSession 类的实例后,您可以调用GetProviderNames() 方法来检索String 对象的集合,这些对象表示计算机上已安装的ETW 提供程序的名称。
以下是从本地计算机检索提供程序名称的示例:
$EventSession = [System.Diagnostics.Eventing.Reader.EventLogSession]::GlobalSession;
$EventProviderNames = $EventSession.GetProviderNames();
$EventProviderNames;
以下是使用alternate constructor 从远程计算机检索 ETW 提供程序名称的示例:
$EventSession = New-Object -TypeName System.Diagnostics.Eventing.Reader.EventLogSession -ArgumentList server01.contoso.com;
$EventProviderNames = $EventSession.GetProviderNames();
$EventProviderNames;
您可以使用EventLogSession 类的不同构造函数来指定远程计算机的备用凭据。 EventLogSession 类的 alternate constructor 需要以下参数:
- 计算机名
- 域名
- 用户名
- 密码(
SecureString)
-
System.Diagnostics.Eventing.Reader.SessionAuthentication 类型
这是一个如何实现的示例:
$ComputerName = 'server01.contoso.com';
$Credential = Get-Credential;
$ArgumentList = $ComputerName, $Credential.UserName.Split('\')[0], $Credential.UserName.Split('\')[1], $Credential.Password, [System.Diagnostics.Eventing.Reader.SessionAuthentication]::Default;
$EventSession = New-Object -TypeName System.Diagnostics.Eventing.Reader.EventLogSession -ArgumentList $ArgumentList;
ETW 日志名称
发现计算机上安装的所有 ETW 提供程序后,您可能还希望浏览计算机上可用的 ETW 日志的完整列表。 EventLogSession 类还有一个名为GetLogNames() 的方法,它返回代表目标系统上可用的ETW 日志的String 对象的集合。与GetProviderNames() 方法类似,您可以在本地或远程计算机上调用GetLogNames()。
以下是从本地计算机检索 ETW 日志名称的示例:
$EventSession = [System.Diagnostics.Eventing.Reader.EventLogSession]::GlobalSession;
$EventLogNames = $EventSession.GetLogNames();
$EventLogNames;
以下是从远程计算机检索 ETW 日志名称的示例:
$EventSession = New-Object -TypeName System.Diagnostics.Eventing.Reader.EventLogSession -ArgumentList server01.contoso.com;
$EventLogNames = $EventSession.GetLogNames();
$EventLogNames;
ETW 提供者元数据
除了检索 ETW 提供程序名称之外,您可能还希望检索有关它们的更详细信息。您可以使用System.Diagnostics.Eventing.Reader .NET 类中的ProviderMetadata 类来执行此操作。 ProviderMetadata 类提供的信息包括:
- 提供者显示名称
- 帮助链接(网址)
- 提供者的关键字
- ETW 提供商 ID (GUID)
- 消息文件路径
- 资源文件路径
- 参数文件路径
- 提供者公开的任务
- 提供者声明的每个事件的事件元数据
与 ETW 提供程序和 ETW 日志名称类似,您可以从本地或远程系统检索提供程序元数据。在后一种情况下,您必须在尝试实例化 ProviderMetadata 类之前建立一个 EventLogSession 实例。
以下是从本地系统检索 ETW 提供程序元数据的示例:
# Get the EventLogSession object
$EventSession = [System.Diagnostics.Eventing.Reader.EventLogSession]::GlobalSession;
# Get the ETW provider names
$EventProviderNames = $EventSession.GetProviderNames();
# Create an empty array to hold the ProviderMetadata instances
$ProviderMetadataList = @();
# For each ETW provider name ...
foreach ($EventProvider in $EventProviderNames) {
# Add each ProviderMetadata instance to the array
$ProviderMetadataList += New-Object -TypeName System.Diagnostics.Eventing.Reader.ProviderMetadata -ArgumentList $EventProvider;
}
# Explore the 16th item from the ProviderMetadata array
$ProviderMetadataList[15];
要从远程系统检索 ETW 提供程序元数据,请在实例化 ProviderMetadata 类之前构建您的 EventLogSession 对象,并且当您实例化 ProviderMetadata 时,请确保将以下参数传递给 constructor:
- ETW 提供商名称
-
EventLogSession 实例
-
CultureInfo 对象
...
$ComputerName = 'server01.contoso.com';
$Credential = Get-Credential;
$SessionArgumentList = $ComputerName, $Credential.UserName.Split('\')[0], $Credential.UserName.Split('\')[1], $Credential.Password, [System.Diagnostics.Eventing.Reader.SessionAuthentication]::Kerberos;
$EventSession = New-Object -TypeName System.Diagnostics.Eventing.Reader.EventLogSession -ArgumentList $SessionArgumentList;
$EventProviderNames = $EventSession.GetProviderNames();
# Create an empty array to hold the ProviderMetadata instances
$ProviderMetadataList = @();
foreach ($EventProvider in $EventProviderNames) {
# Build the Arguments for the ProviderMetadata constructor
$ProviderMetadataArgumentList = $EventProvider, $EventSession, [CultureInfo]::CurrentCulture;
# Add each ProviderMetadata instance to the array
$ProviderMetadataList += New-Object -TypeName System.Diagnostics.Eventing.Reader.ProviderMetadata -ArgumentList $ProviderMetadataArgumentList;
}
# Explore the 111th item from the array
$ProviderMetadataList[110];
注意:当您通过经过身份验证的连接实例化ProviderMetadata 对象时,您可能会遇到一些异常:
New-Object:使用“3”参数调用“.ctor”的异常:“尝试
执行未经授权的操作。”
读取 ETW 事件日志
由于您提到您还想从 ETW 事件日志中读取事件,因此使用 System.Diagnostics.Eventing.Reader .NET 命名空间中的类型也很容易做到这一点。 EventLogReader 类包含一个名为 ReadEvent() 的方法,该方法不断从 EventLogReader 实例化时指定的事件日志中读取下一个事件。
这是一个从系统事件日志中读取事件的简单示例:
# Instantiate the EventLogReader .NET class
$EventLogReader = New-Object -TypeName System.Diagnostics.Eventing.Reader.EventLogReader -ArgumentList 'System';
# Read the first 5 events from the event log
1..5 | % { $EventLogReader.ReadEvent(); };
ETW 事件日志配置
与之前检索的提供程序元数据类似,您可以检索有关特定 ETW 事件日志配置的信息。为此,您需要实例化 EventLogConfiguration class,并传入 ETW 事件日志的名称。将返回有关事件日志的各种信息,包括:
- 日志名称
- 最大大小(以字节为单位)
- 提供者名称
- 日志类型
- 安全描述符
- 缓冲区大小
- 是否启用了日志?
以下是如何检索此信息的示例:
$EventSession = [System.Diagnostics.Eventing.Reader.EventLogSession]::GlobalSession;
$EventLogNames = $EventSession.GetLogNames();
$EventLogConfigurationList = @();
foreach ($EventLogName in $EventLogNames) {
$EventLogConfigurationList += New-Object -TypeName System.Diagnostics.Eventing.Reader.EventLogConfiguration -ArgumentList $EventLogName;
}
$EventLogConfigurationList[5];