这里你可以找到在实际场景中如何使用该模块的实用示例。这些示例旨在帮助你理解如何应用模块的功能。
这些示例提供了更多的深度和背景。如果你只想了解模块命令的用法,请查看命令参考。
这里你可以找到在实际场景中如何使用该模块的实用示例。这些示例旨在帮助你理解如何应用模块的功能。
这些示例提供了更多的深度和背景。如果你只想了解模块命令的用法,请查看命令参考。
本文档概述了在 Active Directory 域环境中运行 DNSServer.DebugLogParser 的一个实际端到端示例,重点是转换域控制器上的 Windows DNS 服务器调试日志。
本示例附带一个 ZIP 压缩包,其中包含用于实现本文描述工作流的策略工件。
最相关的工件包括 备份清单、GPO 报告、Files.xml、Set-DNSServerDebugLogging.ps1 以及 ScheduledTasks.xml。
C:\Administration\Logs\DNSServer)。*.log 文件转换成数据 CSV 和统计 CSV,然后通过计划任务压缩输出为 *.zip。*.zip 输出,例如通过文件共享导入、定时复制、SIEM 转发器或基于代理的收集器。该模型最大限度减少了对大型原始日志文件的网络读取,将解析工作保持在数据近旁。
该工作流通过组策略(计算机配置)实现,确保所有域控制器的设置一致。
本仓库中包含参考实现(GPO 报告):
T0-C-Analytics-DNSDebugLogging{2B6F16BC-0E7C-4787-83D7-2854FED882EE}corp.company.com/Domain ControllersC:\Windows\System32\dns.exe 时应用提供的备份假定以下文件夹已存在。如果希望部署时自动创建,请添加单独的 GPP 项目:
C:\Administration\ScriptsC:\Administration\Logs\DNSServer备份还假定 Convert-DNSDebugLogFile 模块已在 DC 上可用。转换任务启动 Windows PowerShell 5.1,使用 -NoProfile,且不显式导入模块,因此模块必须安装在对 LocalSystem 可见的机器范围 Windows PowerShell 模块路径中。推荐做法:
$env:PSModulePath 中被发现。Import-Module。GPO 部署以下脚本:
%GptPath%\Preferences\Files\Set-DNSServerDebugLogging.ps1C:\Administration\Scripts\Set-DNSServerDebugLogging.ps1此项在 Files.xml 的 GPP 文件首选项中实现。
GPO 创建名为 Set-DNSServerDebugLogging 的计划任务。
SYSTEM,登录类型为 S4U2025-03-01T00:00:01)powershell.exe -ExecutionPolicy RemoteSigned -command " & { C:\Administration\Scripts\Set-DNSServerDebugLogging.ps1 }"C:\Administration\Scripts链接的 Set-DNSServerDebugLogging.ps1 脚本通过 Get-DnsServerDiagnostics / Set-DnsServerDiagnostics 配置 DNS 调试日志,重点包括:
C:\Administration\Logs\DNSServer\DnsDebugLog_<COMPUTERNAME>.<Domain>_.logGPO 创建名为 Convert-DNSDebugLogs 的计划任务。
SYSTEM,登录类型为 InteractiveToken2026-01-01T00:30:00)C:\Administration\Logs\DNSServerGet-ChildItem .\*.log |
Sort-Object lastwritetime, Name -Descending |
Select-Object -Skip 1 |
Convert-DNSDebugLogFile `
-ComputerName $env:COMPUTERNAME `
-Delimiter ';' `
-OutputType Both `
-ContextFilter Packet `
-OutputCulture sv-SE `
-CompressOutput
设计说明:
Select-Object -Skip 1 有意跳过最新(活动)日志文件。-OutputFile 为“同一文件夹,同名,扩展名为 .csv”,输出文件与 *.log 输入文件并列。-CompressOutput 时,每个处理的日志生成一个 *.zip,并删除中间 CSV 文件。*.log 文件,否则后续运行会再次处理所有非活动日志。$Error.Count -gt 0 时抛出异常,表示运行失败。选项(任选其一):
C:\Administration\Logs\DNSServer\*.zip 到 \\fileserver\share\dns\$env:COMPUTERNAME\...(为 DC 计算机账户或域控制器组授予共享和 NTFS 权限,若任务以 SYSTEM 运行)\\dc\C$\Administration\Logs\DNSServer\*.zip(最不推荐,需管理员共享)*.zip 输出SYSTEM 运行;确保本地文件夹可写,且任何 UNC 目标对计算机账户开放访问(如使用)。-ExecutionPolicy RemoteSigned;根据策略签署或解除阻止部署的脚本和模块。-CompressOutput 显著减少空间,但该工作流不删除源日志;请规划保留和清理策略。*.log 文件。此方法简单且稳健,但可能覆盖输出并在收集器不去重时产生重复数据。-ComputerName $env:COMPUTERNAME,确保合并数据集可追溯。-SkipHeaderValidation(推荐做法)。使用 ZIP 压缩包 作为参考实现,然后根据环境调整以下方面:
S4U 与 InteractiveToken),或统一为标准C:\Administration\Scripts 和 C:\Administration\Logs\DNSServer,或由额外 GPP 项目创建C:\Administration\Scripts 和 C:\Administration\Logs\DNSServer 符合标准如果想在不导入的情况下验证 GPO 配置,仓库中的权威资源包括:
此示例展示了一个实用的安全分析工作流:使用 Convert-DNSDebugLogFile 解析 DNS 调试日志,将生成的 CSV 导入 SQL Server,并运行查询以突出显示异常大量的 TXT 记录查询。
为了最佳的互操作性,此示例通过使用 -OutputCulture 'sv-SE' 以类似 ISO 的格式写入时间戳。
此示例使用以下 PowerShell 模块:
DNSServer.DebugLogParserSqlServer如有需要,请安装它们:
Install-Module -Name DNSServer.DebugLogParser -Scope CurrentUser
Install-Module -Name SqlServer -Scope CurrentUser
当你想将解析后的 DNS 调试日志数据移入 SQL Server,以便你可以:
时,请使用此工作流。
Convert-DNSDebugLogFile 不直接写入 SQL Server。它首先创建一个 CSV 文件。该 CSV 文件即为导入数据库的数据集。
在此示例中:
C:\Administration\Logs\DNS\dns.logC:\Administration\Logs\DNS\dns.csvdbo.DNSQueries在 SQL Server 中运行以下语句一次,创建目标表。
IF OBJECT_ID('dbo.DNSQueries', 'U') IS NULL
BEGIN
CREATE TABLE dbo.DNSQueries (
DateTime datetime2(0) NOT NULL,
ThreadId int NULL,
Context nvarchar(20) NULL,
PacketId int NULL,
Protocol nvarchar(10) NULL,
Direction nvarchar(10) NULL,
ClientIP nvarchar(64) NULL,
Xid nvarchar(16) NULL,
Type nvarchar(16) NULL,
Opcode nvarchar(16) NULL,
FlagsHex nvarchar(16) NULL,
FlagsChar nvarchar(16) NULL,
ResponseCode nvarchar(32) NULL,
QuestionType nvarchar(32) NULL,
QuestionName nvarchar(512) NULL,
Information nvarchar(max) NULL,
Details nvarchar(max) NULL,
ComputerName nvarchar(256) NULL
);
END;
以下 PowerShell 示例执行完整工作流:
# Requires -Modules DNSServer.DebugLogParser, SqlServer
Import-Module -Name DNSServer.DebugLogParser -ErrorAction Stop
Import-Module -Name SqlServer -ErrorAction Stop
$logPath = 'C:\Administration\Logs\DNS\dns.log'
$csvPath = 'C:\Administration\Logs\DNS\dns.csv'
$serverInstance = 'SQLServer'
$databaseName = 'DNSLogs'
$delimiter = ';'
$createTableSql = @'
IF OBJECT_ID('dbo.DNSQueries', 'U') IS NULL
BEGIN
CREATE TABLE dbo.DNSQueries (
DateTime datetime2(0) NOT NULL,
ThreadId int NULL,
Context nvarchar(20) NULL,
PacketId int NULL,
Protocol nvarchar(10) NULL,
Direction nvarchar(10) NULL,
ClientIP nvarchar(64) NULL,
Xid nvarchar(16) NULL,
Type nvarchar(16) NULL,
Opcode nvarchar(16) NULL,
FlagsHex nvarchar(16) NULL,
FlagsChar nvarchar(16) NULL,
ResponseCode nvarchar(32) NULL,
QuestionType nvarchar(32) NULL,
QuestionName nvarchar(512) NULL,
Information nvarchar(max) NULL,
Details nvarchar(max) NULL,
ComputerName nvarchar(256) NULL
);
END
'@
Convert-DNSDebugLogFile `
-InputFile $logPath `
-ComputerName 'DNS01' `
-OutputType CSV `
-OutputFile $csvPath `
-Delimiter $delimiter `
-OutputCulture 'sv-SE'
$rows = Import-Csv -Path $csvPath -Delimiter $delimiter
if (-not $rows) {
throw "生成的 CSV 文件 '$csvPath' 不包含任何行。"
}
$dataTable = [System.Data.DataTable]::new()
foreach ($columnName in $rows[0].PSObject.Properties.Name) {
$null = $dataTable.Columns.Add($columnName, [string])
}
foreach ($row in $rows) {
$dataRow = $dataTable.NewRow()
foreach ($column in $dataTable.Columns) {
$columnName = $column.ColumnName
$dataRow[$columnName] = $row.$columnName
}
$null = $dataTable.Rows.Add($dataRow)
}
$connectionString = "Server=$serverInstance;Database=$databaseName;Integrated Security=True"
$connection = [System.Data.SqlClient.SqlConnection]::new($connectionString)
try {
$connection.Open()
$command = $connection.CreateCommand()
$command.CommandText = $createTableSql
$null = $command.ExecuteNonQuery()
$bulkCopy = [System.Data.SqlClient.SqlBulkCopy]::new($connection)
$bulkCopy.DestinationTableName = 'dbo.DNSQueries'
foreach ($column in $dataTable.Columns) {
$null = $bulkCopy.ColumnMappings.Add($column.ColumnName, $column.ColumnName)
}
$bulkCopy.WriteToServer($dataTable)
}
finally {
$connection.Dispose()
}
数据进入 SQL Server 后,你可以搜索发出异常大量 TXT 记录查询的客户端。
SELECT
ComputerName,
ClientIP,
QuestionName,
COUNT(*) AS QueryCount
FROM dbo.DNSQueries
WHERE QuestionType = 'TXT'
GROUP BY
ComputerName,
ClientIP,
QuestionName
HAVING COUNT(*) > 100
ORDER BY QueryCount DESC;
如果你更喜欢从 PowerShell 运行查询,可以使用 SqlServer 模块中的 Invoke-Sqlcmd:
$query = @'
SELECT
ComputerName,
ClientIP,
QuestionName,
COUNT(*) AS QueryCount
FROM dbo.DNSQueries
WHERE QuestionType = 'TXT'
GROUP BY
ComputerName,
ClientIP,
QuestionName
HAVING COUNT(*) > 100
ORDER BY QueryCount DESC;
'@
Invoke-Sqlcmd `
-ServerInstance 'SQLServer' `
-Database 'DNSLogs' `
-Query $query
大量的 TXT 记录查询值得关注,因为它们可能表明:
此查询只是一个起点。在生产环境中,你应调整阈值并添加符合你环境的过滤条件。
Import-Csv 会将整个文件读入内存。对于非常大的日志导出,考虑使用流式处理而非构建完整的 DataTable。-ComputerName,以便在集中摄取后仍能归属记录。此脚本创建了一个每天凌晨 2:00 运行的 Windows 计划任务。它导入模块并处理脚本执行所在文件夹中的所有日志文件(本例中为 “C:\Administration\Logs\DNS”)。该过程会将输出压缩成 ZIP 文件,并删除原始文件以保持整洁。
$actionParams = @{
Execute = "powershell.exe"
Argument = '-ExecutionPolicy RemoteSigned -Command "Import-Module DNSServer.DebugLogParser; Get-ChildItem .\*.log | Sort-Object lastwritetime, Name -Descending | Convert-DNSDebugLogFile -ComputerName $env:COMPUTERNAME -Delimiter \";\" -OutputType Both -ContextFilter Packet -OutputCulture sv-SE -CompressOutput"'
WorkingDirectory = "C:\Administration\Logs\DNS"
}
$Action = New-ScheduledTaskAction @actionParams
$Trigger = New-ScheduledTaskTrigger -Daily -At "2:00AM"
Register-ScheduledTask -TaskName "Process DNS Logs" -Action $Action -Trigger $Trigger -Description "Convert DNS debug logs to CSV daily"