当前位置:网站首页>使用 PowerShell 将 Windows 转发事件导入 SQL Server
使用 PowerShell 将 Windows 转发事件导入 SQL Server
2022-08-03 15:58:00 【allway2】
在过去的几周里,我研究了多种解析Windows 转发事件并将其导入SQL Server 的方法:从使用 SSIS 到 LogParser 到 PowerShell,再到将链接服务器设置为“Forwarding Events.evtx”文件。
最终,唯一有效的是 PowerShell 的 Get-WinEvent cmdlet。然后,它只适用于我的一个特定情况——如果事件是在 Windows 2012 服务器上收集和解析的。截至今天,Get-WinEvent 中存在一个未解决的错误,该错误通常导致 NULL LevelDisplayName、Message 和 TaskDisplayName 列。我在 Win2k8 R2 服务器和 Win 8 工作站上复制了下面的确切代码,并反复遇到 NULLs 问题。但是,您的结果可能会有所不同,因为一些用户报告通过在 Win2k8 R2 Server 中调整一些东西取得了成功。
因此,启动一个 Windows 2012 机器,设置您的 SQL Server,让我们开始吧:
SQL 部分
查看Get-WinEvent返回的数据后,我发现以下列最有用:ID、LevelDisplayName、LogName、MachineName、Message、ProviderName、RecordID、TaskDisplayName、TimeCreated。然后我使用这些列创建了一个表:
CREATE DATABASE EventCollections
GO
USE EventCollections
GO
-- the table name loosely relates to the name of my Win Event Subscription name
CREATE TABLE [dbo].[GeneralEvents](
[Id] [int] NULL,
[LevelDisplayName] [varchar](255) NULL,
[LogName] [varchar](255) NULL,
[MachineName] [varchar](255) NULL,
[Message] [varchar](max) NULL,
[ProviderName] [varchar](255) NULL,
[RecordID] [bigint] NULL,
[TaskDisplayName] [varchar](255) NULL,
[TimeCreated] [smalldatetime] NULL
)
-- Create Unique Clustered Index with IGNORE_DUPE_KEY=ON to avoid duplicates in sqlbulk imports
CREATE UNIQUE CLUSTERED INDEX [ClusteredIndex-EventCombo] ON [dbo].[GeneralEvents]
(
[RecordID] ASC,
[MachineName] ASC,
[LogName] ASC
) WITH (IGNORE_DUP_KEY = ON)
GO
为了避免在每小时导入期间出现重复,我使用 IGNORE_DUP_KEY = ON 在 3 列上的唯一索引创建了表:RecordID、MachineName 和 LogName。
接下来,我必须决定如何将数据从 PowerShell 获取到 SQL Server。在阅读了sqlservercentral.com和technet之后,我决定使用sqlbulkcopy
.
PowerShell 部分
转发事件是一件棘手的事情。出于某种原因,通常使用FilterHasTable过滤 Get-WinEvent 结果的方式一直返回结果Get-WinEvent :未找到与指定选择条件匹配的事件。我发现许多其他人也遇到了这个问题,当人们尝试使用 LogParser 时也发生了类似的错误。毕竟,我对 FilterXML 的工作没有太大希望,但它确实做到了!因此,我们将在执行初始导入后使用它。
这是initial import
在转发事件中收集所有事件的代码。
$events = Get-WinEvent ForwardedEvents | Select-Object ID, LevelDisplayName, LogName, MachineName, Message, ProviderName, RecordID, TaskDisplayName, TimeCreated
$connectionString = "Data Source=sqlserver;Integrated Security=true;Initial Catalog=EventCollections;"
$bulkCopy = new-object ("Data.SqlClient.SqlBulkCopy") $connectionString
$bulkCopy.DestinationTableName = "GeneralEvents"
$dt = New-Object "System.Data.DataTable"
# build the datatable
$cols = $events | select -first 1 | get-member -MemberType NoteProperty | select -Expand Name
foreach ($col in $cols) {$null = $dt.Columns.Add($col)}
foreach ($event in $events)
{
$row = $dt.NewRow()
foreach ($col in $cols) { $row.Item($col) = $event.$col }
$dt.Rows.Add($row)
}
# Write to the database!
$bulkCopy.WriteToServer($dt)
您可能已经注意到我手动构建了一个数据表,而不是使用Out-DataTable.ps1,这似乎是粉丝的最爱。我觉得上面的代码让事情变得更加整洁,性能仍然相当不错。
由于事件收集是一个持续的事情,您可能希望定期导入它们。我通过右键单击事件查看器中的转发事件->过滤当前日志...->记录:(更改为一小时)->单击顶部的 XML 选项卡->复制/粘贴->瞧,构建了必要的 XML 查询。
实际上,使用这个查询的语法,我找到了 FilterHashTable 的语法,但是让 GUI 构建我的查询很容易,所以我坚持了下来。这是hourly import
您可以在任务计划程序中设置的代码。
# While this script is intended to run on an hourly basis, the filter is set for going back 65 minutes.
# This allows the script to run for 5 minutes without any missing any events. Because we setup the
# table using the IGNORE_DUPE_KEY = ON, duplicate entries are ignored in the database.
$xml = @'
<QueryList>
<Query Id="0" Path="ForwardedEvents">
<Select Path="ForwardedEvents">*[System[TimeCreated[timediff(@SystemTime) <= 3900000]]]</Select>
</Query>
</QueryList>
'@
$events = Get-WinEvent -FilterXml $xml | Select-Object ID, LevelDisplayName, LogName, MachineName, Message, ProviderName, RecordID, TaskDisplayName, TimeCreated
$connectionString = "Data Source=sqlserver;Integrated Security=true;Initial Catalog=EventCollections;"
$bulkCopy = new-object ("Data.SqlClient.SqlBulkCopy") $connectionString
$bulkCopy.DestinationTableName = "GeneralEvents"
$dt = New-Object "System.Data.DataTable"
# build the datatable
$cols = $events | select -first 1 | get-member -MemberType NoteProperty | select -Expand Name
foreach ($col in $cols) {$null = $dt.Columns.Add($col)}
foreach ($event in $events)
{
$row = $dt.NewRow()
foreach ($col in $cols) { $row.Item($col) = $event.$col }
$dt.Rows.Add($row)
}
# Write to the database!
$bulkCopy.WriteToServer($dt)
运气好的话,您的 SQL 输出应该如下所示:
边栏推荐
- 【Unity入门计划】基本概念(6)-精灵渲染器 Sprite Renderer
- JS基础--判断
- Reptile attention
- Essentially a database data recovery 】 【 database cannot read data recovery case
- STM32 GPIO LED和蜂鸣器实现【第四天】
- Introduction to the advantages of the new generation mesh network protocol T-Mesh wireless communication technology
- 如何选择合适的损失函数,请看......
- 元宇宙系列--Value creation in the metaverse
- Fortinet产品导入AWS AMI操作文档
- ReentrantReadWriteLock详解
猜你喜欢
随机推荐
posgresql 到 es 报这个错误 ,啥意思
STM32 GPIO LED和蜂鸣器实现【第四天】
生态剧变,电子签名SaaS模式迎来新突破,网络效应加速到来
袁小林:沃尔沃专注于出行的安全感,并且把它做到极致
为什么我强烈推荐使用智能化async?
出海季,互联网出海锦囊之本地化
高可用版 主数据库数据结构改变 备数据库会自动改变吗
深入浅出Flask PIN
详谈RDMA技术原理和三种实现方式
简易网络传输方法
攻防世界----bug
Ruoyi Ruoyi framework @DataScope annotation use and some problems encountered
实时渲染流程操作复杂吗,如何实现?
AI+BI+Visualization, Deep Analysis of Sugar BI Architecture
CS免杀姿势
深度学习GPU最全对比,到底谁才是性价比之王?
5 v 8.4 v1A charging current charging management IC
Neural networks, cool?
Tolstoy: There are only two misfortunes in life
Small Tools (4) integrated Seata1.5.2 distributed transactions