<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>About this documentation on PowerShell module DNSServer.DebugLogParser</title><link>https://DNSServerDebugLogParser.andibellstedt.com/docs/</link><description>Recent content in About this documentation on PowerShell module DNSServer.DebugLogParser</description><generator>Hugo</generator><language>en</language><lastBuildDate>Mon, 01 Jan 0001 00:00:00 +0000</lastBuildDate><atom:link href="https://DNSServerDebugLogParser.andibellstedt.com/docs/index.xml" rel="self" type="application/rss+xml"/><item><title>Overview</title><link>https://DNSServerDebugLogParser.andibellstedt.com/docs/01-overview/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://DNSServerDebugLogParser.andibellstedt.com/docs/01-overview/</guid><description>&lt;p&gt;Windows DNS Server can write a debug log. It is a plain text file, it is meant to be read by a human, and it grows by hundreds of megabytes a day on a busy domain controller. That combination makes it nearly useless the moment you want to answer a question like &lt;em&gt;&amp;ldquo;which client asked for this domain 40.000 times last night?&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DNSServer.DebugLogParser&lt;/strong&gt; turns that text file into a CSV table. One log line becomes one row with named columns, so you can open it in Excel, load it into Power BI, bulk-insert it into SQL Server, or ship it to your SIEM.&lt;/p&gt;</description></item><item><title>Output Formats</title><link>https://DNSServerDebugLogParser.andibellstedt.com/docs/02-output-formats/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://DNSServerDebugLogParser.andibellstedt.com/docs/02-output-formats/</guid><description>&lt;p&gt;&lt;code&gt;Convert-DNSDebugLogFile&lt;/code&gt; produces up to three files per input log:&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;File&lt;/th&gt;
					&lt;th&gt;Contains&lt;/th&gt;
					&lt;th&gt;Created when&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;&amp;lt;name&amp;gt;.csv&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;One row per parsed log entry&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;-OutputType CSV&lt;/code&gt; or &lt;code&gt;Both&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;&amp;lt;name&amp;gt;_Statistic.csv&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Daily record count per context&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;-OutputType Statistic&lt;/code&gt; or &lt;code&gt;Both&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;&amp;lt;name&amp;gt;_PacketStatistic.csv&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;Daily query count per client, protocol, direction and record type&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;-OutputType Statistic&lt;/code&gt; or &lt;code&gt;Both&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;Both&lt;/code&gt; is the default. Output lands next to the input file unless you set &lt;code&gt;-OutputFile&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The sample files linked on this page are real conversion results, not mock-ups. Download one and open it in Excel before you commit to a pipeline design.&lt;/p&gt;</description></item><item><title>Parameters and Options</title><link>https://DNSServerDebugLogParser.andibellstedt.com/docs/03-parameters-and-options/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://DNSServerDebugLogParser.andibellstedt.com/docs/03-parameters-and-options/</guid><description>&lt;p&gt;This page explains the options in plain language and in the order you will typically need them. It is a guide, not a specification — the authoritative, always-current parameter list lives in the &lt;a href="../commands/convert-dnsdebuglogfile/"&gt;command reference&lt;/a&gt; and in:&lt;/p&gt;
&lt;pre&gt;&lt;code class="language-powershell"&gt;Get-Help Convert-DNSDebugLogFile -Full
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="the-short-version"&gt;The short version&lt;/h2&gt;
&lt;pre&gt;&lt;code class="language-powershell"&gt;Convert-DNSDebugLogFile -InputFile &amp;quot;C:\Logs\dns.log&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That single line already gives you sensible behaviour: both data and statistics files, semicolon delimiter, your machine&amp;rsquo;s date format, header validation on, source log untouched. Everything below is fine-tuning.&lt;/p&gt;</description></item><item><title>Performance</title><link>https://DNSServerDebugLogParser.andibellstedt.com/docs/04-performance/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://DNSServerDebugLogParser.andibellstedt.com/docs/04-performance/</guid><description>&lt;p&gt;DNS debug logs on a busy domain controller are big. &lt;code&gt;Convert-DNSDebugLogFile&lt;/code&gt; is built for that case: it has been tested with logs of 100 MB and beyond, and it processes them in minutes on ordinary server hardware.&lt;/p&gt;
&lt;h2 id="why-it-is-fast"&gt;Why it is fast&lt;/h2&gt;
&lt;p&gt;You do not need to know any of this to use the module, but it explains the behaviour you will observe.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Technique&lt;/th&gt;
					&lt;th&gt;Effect you notice&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;code&gt;StreamReader&lt;/code&gt; / &lt;code&gt;StreamWriter&lt;/code&gt; with 64 KB buffers&lt;/td&gt;
					&lt;td&gt;The file is read and written in chunks instead of one big &lt;code&gt;Get-Content&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Streaming, single pass&lt;/td&gt;
					&lt;td&gt;Memory usage stays roughly flat no matter how large the log is&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;String operations (&lt;code&gt;.Substring()&lt;/code&gt;, &lt;code&gt;.IndexOf()&lt;/code&gt;) instead of regular expressions&lt;/td&gt;
					&lt;td&gt;Considerably less CPU per line, and there are millions of lines&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;CSV written by hand instead of &lt;code&gt;Export-Csv&lt;/code&gt;&lt;/td&gt;
					&lt;td&gt;No object pipeline overhead per record&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Hashtable-based aggregation for statistics&lt;/td&gt;
					&lt;td&gt;Rollups cost almost nothing extra during the same pass&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The important consequence: &lt;strong&gt;the whole log is never held in memory.&lt;/strong&gt; A 500 MB log does not need 500 MB of RAM. This is the difference between the module and the &amp;ldquo;read the file, split it, build objects&amp;rdquo; approach most home-grown scripts take — that approach works fine on a 5 MB sample and falls over on a real DC.&lt;/p&gt;</description></item><item><title>Integration with Analysis Tools</title><link>https://DNSServerDebugLogParser.andibellstedt.com/docs/05-integration/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://DNSServerDebugLogParser.andibellstedt.com/docs/05-integration/</guid><description>&lt;p&gt;The point of converting a DNS debug log is what happens next. CSV was chosen because everything reads it — but &amp;ldquo;everything reads CSV&amp;rdquo; hides two settings that decide whether an import is painless or an afternoon of fiddling.&lt;/p&gt;
&lt;h2 id="two-settings-that-decide-everything"&gt;Two settings that decide everything&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Delimiter.&lt;/strong&gt; Default is &lt;code&gt;;&lt;/code&gt;. Keep it for Excel in locales that use the comma as decimal separator. Switch to &lt;code&gt;,&lt;/code&gt; for most databases and data-science tooling. Whatever you choose, tell the importing side the same thing.&lt;/p&gt;</description></item><item><title>Operational Best Practices</title><link>https://DNSServerDebugLogParser.andibellstedt.com/docs/06-operational-best-practices/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://DNSServerDebugLogParser.andibellstedt.com/docs/06-operational-best-practices/</guid><description>&lt;p&gt;Converting a log by hand is easy. Running it every night on every domain controller, for years, without anyone looking at it, is the part that needs a bit of design. These are the points that matter in practice.&lt;/p&gt;
&lt;h2 id="1-convert-rotated-logs-not-the-active-one"&gt;1. Convert rotated logs, not the active one&lt;/h2&gt;
&lt;p&gt;Enable log rollover on the DNS server and convert only closed files. The module &lt;em&gt;can&lt;/em&gt; read the log DNS Server is currently writing to, but that file changes underneath the conversion: the newest entries may be missing and the last record may be truncated. Two runs produce two different results.&lt;/p&gt;</description></item><item><title>Troubleshooting</title><link>https://DNSServerDebugLogParser.andibellstedt.com/docs/08-troubleshooting/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://DNSServerDebugLogParser.andibellstedt.com/docs/08-troubleshooting/</guid><description>&lt;h2 id="the-file-is-not-a-valid-dns-debug-log-file"&gt;&amp;ldquo;The file is not a valid DNS debug log file&amp;rdquo;&lt;/h2&gt;
&lt;p&gt;The header check rejected the input. Usually the path is simply wrong — a &lt;code&gt;.log&lt;/code&gt; file in the same folder that is not the DNS debug log, or a file that only contains a rotated header.&lt;/p&gt;
&lt;p&gt;Work through this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Open the file. A DNS debug log starts with a header line such as &lt;code&gt;Message logging started at …&lt;/code&gt; and continues with timestamped query entries.&lt;/p&gt;</description></item></channel></rss>