我想使用Windows PowerShell检索有关事件提供程序的信息吗?我在运行Windows 8.1和PowerShell版本4.0,并且注意到 System.Diagnostics.Eventing namespace中有一些.NET类,它们提供了有关Windows事件的某些功能。

我可以通过调用其默认构造函数来创建EventProvider实例,但是,这不允许我获取有关系统上安装的事件提供程序的任何信息。

$EventProvider = New-Object -TypeName System.Diagnostics.Eventing.EventProvider -ArgumentList ([System.Guid]'{00000000-0000-0000-0000-000000000000}');

如何使用Windows PowerShell获得有关系统上安装的Windows事件跟踪(ETW)提供程序并与Windows事件日志进行交互的更多信息?

我已经知道我可以使用described here命令logman.exe query providers来检索ETW提供程序列表,并查询Windows事件日志,但这对PowerShell不太友好。

最佳答案

还有另一个.oji命名空间System.Diagnostics.Eventing.Reader,它包含更多的.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的静态属性,该属性自动检索与本地计算机上的事件日志服务的 session /连接。如有必要,您也可以使用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()的方法,该方法返回String对象的集合,这些对象表示目标系统上可用的ETW日志。与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提供程序名称之外,您可能还希望获取有关它们的更详细的信息。您可以使用ProviderMetadata .NET类中的System.Diagnostics.Eventing.Reader类来完成此操作。 ProviderMetadata类提供的信息包括:
  • 提供程序显示名称
  • 帮助链接(URL)
  • 提供者的关键字
  • ETW提供者ID(GUID)
  • 消息文件路径
  • 资源文件路径
  • 参数文件路径
  • 提供程序
  • 公开的任务
  • 提供程序
  • 声明的每个事件的事件元数据

    与ETW提供程序和ETW日志名称类似,您可以从本地或远程系统检索提供程序元数据。在后一种情况下,必须先建立EventLogSession实例,然后再尝试实例化ProviderMetadata类。

    这是从本地系统检索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提供程序元数据,请在实例化EventLogSession类之前构建ProviderMetadata对象,并在实例化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对象时,您可能会遇到一些异常:



    读取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];
    

    关于.net - 获取Windows事件提供程序信息,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21012622/

    10-16 23:56