Questa è la versione stampabile multipagina di questa sezione. Clicca qui per stampare.

Torna alla visualizzazione normale di questa pagina.

Informazioni su questa documentazione

Questo è il sito ufficiale della documentazione per DNSServer.DebugLogParser, un modulo PowerShell che trasforma i file di log di debug del server DNS di Windows in dati CSV strutturati e analizzabili.

Informazioni sul modulo

DNSServer.DebugLogParser nasce da una necessità reale: i log di debug del server DNS di Windows sono testi leggibili dall’uomo, ma non adatti per analisi o reportistica. Questo modulo colma questa lacuna convertendo i file di log grezzi in un formato CSV strutturato che si integra con strumenti comuni come Excel, Power BI, database SQL e sistemi SIEM.

Principi chiave di progettazione:

  • Performance prima di tutto — ottimizzato per file da 100MB+ usando I/O in streaming e operazioni su stringhe
  • Compatibilità cross-edizione — supporta PowerShell Desktop (5.1+) e Core (7.x)
  • Pronto per la produzione — include validazione dell’intestazione, gestione degli errori e compressione opzionale
  • Pipeline-friendly — si integra naturalmente con l’architettura a pipeline di PowerShell

Cosa c’è qui

SezioneLeggila quando
PanoramicaVuoi sapere cosa fa il modulo e se si adatta al tuo problema
Formati di outputDevi capire cosa significano le colonne CSV prima di progettare una pipeline
Parametri e opzioniStai decidendo quali switch servono alla tua conversione
PrestazioniI tuoi log sono grandi o la conversione è più lenta del previsto
IntegrazioneStai caricando i risultati in Excel, Power BI, SQL, un SIEM o Python
Best practice operativeStai per eseguire questo in produzione senza supervisione
Esempi d’usoVuoi uno scenario completo da adattare
Risoluzione problemiQualcosa non si comporta come previsto
Riferimento comandiTi serve la lista autorevole dei parametri

Se sei nuovo al modulo, inizia dalla Panoramica.

Risorse

Contribuire

I contributi sono benvenuti. Se trovi problemi, errori o hai suggerimenti per miglioramenti, apri una issue o una pull request sul repository GitHub.

1 - Panoramica

Cosa fa DNSServer.DebugLogParser, com’è fatto un log di debug DNS di Windows, e quando vale la pena convertirlo in CSV.

Windows DNS Server può scrivere un log di debug. È un file di testo semplice, pensato per essere letto da un umano, e cresce di centinaia di megabyte al giorno su un controller di dominio molto attivo. Questa combinazione lo rende quasi inutile nel momento in cui vuoi rispondere a una domanda come “quale client ha richiesto questo dominio 40.000 volte la scorsa notte?”

DNSServer.DebugLogParser trasforma quel file di testo in una tabella CSV. Una riga di log diventa una riga con colonne nominate, così puoi aprirla in Excel, caricarla in Power BI, inserirla in blocco in SQL Server o inviarla al tuo SIEM.

Il modulo contiene un solo comando:

Convert-DNSDebugLogFile -InputFile "C:\Windows\System32\dns\dns.log"

Questo è tutto il punto di ingresso. Tutto il resto in questo sito riguarda come farlo su larga scala, con una pianificazione e su più server.

Com’è fatto un log di debug DNS

Una voce grezza è una singola riga con campi posizionali, alcuni racchiusi tra parentesi:

2026-01-20 23:00:16 0FE0 PACKET 000002C53117D990 UDP Rcv 10.0.0.2 c049 Q [0001 D NOERROR] A (3)odc(9)officeapps(4)live(3)com(0)

Dopo la conversione, lo stesso evento diventa una riga CSV che puoi filtrare e ordinare:

DateTime;ThreadId;Context;PacketId;Protocol;Direction;ClientIP;Xid;Type;Opcode;FlagsHex;FlagsChar;ResponseCode;QuestionType;QuestionName;Information;Details;ComputerName
2026-01-20 23:00:16;0FE0;Packet;000002C53117D990;UDP;Rcv;10.0.0.2;c049;Query;Standard;0001;RecursionDesired;NOERROR;A;"odc.officeapps.live.com";"";"";dc01

Nota due cose che il formato grezzo rende difficili e che il parser gestisce per te:

  • Il nome interrogato è memorizzato nella notazione wire DNS, (3)odc(9)officeapps(4)live(3)com(0), e diventa un FQDN normale.
  • Un singolo evento non è sempre una singola riga. I blocchi di dettaglio PACKET e i messaggi di evento continuano su righe successive indentate. Il parser li mantiene collegati al record a cui appartengono invece di scartarli o creare righe orfane.

Ogni voce contiene fino a 16 campi nativi — timestamp, protocollo, direzione, IP client, tipo di query, nome interrogato, codice di risposta, flag e altro. L’elenco completo delle colonne è descritto in Output Formats.

Perché vale la pena convertire

Risoluzione dei problemi

  • Scoprire perché un nome non si risolve e se la query è arrivata al server
  • Identificare client o applicazioni mal configurati che sovraccaricano il server
  • Tracciare da dove proviene una query problematica
  • Verificare i trasferimenti di zona e il comportamento generale del DNS

Prestazioni e capacità

  • Classificare i client per volume di query e trovare quelli rumorosi
  • Vedere quali tipi di record dominano il traffico
  • Individuare errori di configurazione che causano lookup evitabili
  • Monitorare il carico del server nel tempo invece di indovinare

Analisi di sicurezza

  • Rilevare tunneling DNS ed esfiltrazione dati (tipicamente visibile come traffico TXT eccessivo — vedi l’esempio di analisi SQL Server)
  • Trovare lookup verso domini di malware e command-and-control
  • Riconoscere pattern di query di un host compromesso
  • Sorvegliare abusi di amplificazione DNS
  • Ricostruire cosa è successo durante un incidente

Conformità e auditing

  • Soddisfare obblighi di logging e conservazione
  • Tenere traccia delle attività di rete
  • Produrre report per la direzione o gli auditor

Come funziona il modulo

Convert-DNSDebugLogFile legge il log come stream e scrive il CSV come stream. Il file non viene mai caricato interamente in memoria, quindi un log da 100 MB consuma più o meno la stessa RAM di uno da 10 MB. I dettagli sono in Performance.

Cosa ti offre:

FunzionalitàDettaglio
Layout CSV coerente18 colonne, sempre nello stesso ordine, indipendentemente dai contesti presenti nel log
Record multilineaI blocchi di dettaglio PACKET e il testo degli eventi restano collegati al loro record
Versioni di DNS ServerFormati di log da 2012 R2 fino al 2025
Edizioni di PowerShellWindows PowerShell 5.1+ e PowerShell 7.x
Dimensione fileTestato con log da oltre 100 MB; streaming in singola passata
Validazione headerRifiuta file che non sono log di debug DNS (disattivabile)
StatisticheRollup giornalieri opzionali, per contesto e per client/protocollo/tipo
Supporto pipelineGet-ChildItem *.log | Convert-DNSDebugLogFile
CompressioneOutput ZIP opzionale, tipicamente oltre il 90% più piccolo
Pulizia sorgenteCancellazione opzionale del log dopo una conversione riuscita
Log internazionaliAnalizza e scrive date per cultura, così un log de-DE può essere letto su una workstation en-US
Percorsi di reteLegge da percorsi SMB/UNC
File bloccatiLegge log che DNS Server (o altro) ha attualmente aperti

Log attivo vs. log ruotato

Il modello pratico è abilitare il rollover del log sul server DNS e far saltare la conversione pianificata del file più recente:

Get-ChildItem "C:\Administration\Logs\DNSServer\*.log" |
    Sort-Object LastWriteTime -Descending |
    Select-Object -Skip 1 |
    Convert-DNSDebugLogFile -ComputerName $env:COMPUTERNAME

Un’implementazione completa basata su Group Policy è documentata nell’esempio di raccolta guidata da GPO.

Dove andare dopo

Licenze e supporto

Licenza MIT. Il supporto comunitario avviene tramite GitHub Issues; segnalazioni di bug e richieste di funzionalità sono benvenute.

2 - Formati di Output

Le colonne del file dati CSV, i due file opzionali di statistiche e esempi reali di output che puoi aprire prima di eseguire qualsiasi operazione.

Convert-DNSDebugLogFile produce fino a tre file per ogni log di input:

FileContenutoCreato quando
<name>.csvUna riga per ogni voce di log analizzata-OutputType CSV o Both
<name>_Statistic.csvConteggio giornaliero dei record per contesto-OutputType Statistic o Both
<name>_PacketStatistic.csvConteggio giornaliero delle query per client, protocollo, direzione e tipo di record-OutputType Statistic o Both

Both è il valore predefinito. L’output viene salvato accanto al file di input a meno che non imposti -OutputFile.

I file di esempio collegati in questa pagina sono risultati di conversioni reali, non simulazioni. Scaricane uno e aprilo in Excel prima di decidere come progettare la pipeline.

Il file dati CSV

Esempio di output:

LocaleColonna DettagliFile
en-USnon popolataWithComputerName, NoComputerName
de-DEnon popolataWithComputerName, NoComputerName
de-DEpopolataWithComputerName, NoComputerName

Due righe da una conversione reale — una query DNS e una nota interna al server:

DateTime;ThreadId;Context;PacketId;Protocol;Direction;ClientIP;Xid;Type;Opcode;FlagsHex;FlagsChar;ResponseCode;QuestionType;QuestionName;Information;Details;ComputerName
2026-01-20 23:00:16;0FE0;Packet;000002C53117D990;UDP;Rcv;10.0.0.2;c049;Query;Standard;0001;RecursionDesired;NOERROR;A;"odc.officeapps.live.com";"";"";dc01
2026-01-20 23:00:16;DF0;Note;;;;;;;;;;;;"";"got GQCS failure on a dead socket context status=995, socket=904";"";dc01

Colonne

Sempre 18 colonne, sempre in questo ordine:

#ColonnaSignificatoUso tipico
1DateTimeTimestamp della voceFiltraggio temporale, unione con altri log
2ThreadIdThread di lavoro del server DNSRaramente necessario; utile per correlare problemi interni al server
3ContextTipo di voce: Packet, Event, Note, DSPoll, Init, Lookup, Recurse, Remote, TombstonePrimo filtro da applicare — Packet è il traffico DNS vero e proprio
4PacketIdIdentificatore interno del pacchettoAbbinare una query alla sua risposta
5ProtocolUDP o TCPPicchi TCP possono indicare risposte grandi o trasferimenti di zona
6DirectionRcv (query ricevuta) o Snd (server ha risposto)Separare volume richieste da volume risposte
7ClientIPIndirizzo dell’host che ha fatto la queryAnalisi dei top talker, definizione dell’incidente
8XidID transazione DNS (esadecimale)Abbinare richiesta e risposta
9TypeQuery o Response
10OpcodeStandard, Notify, Update, UnknownSeparare aggiornamenti dinamici e notifiche di zona dalle normali ricerche
11FlagsHexFlag header grezzi (esadecimale)Per analisi approfondite del protocollo
12FlagsCharFlag decodificati: Authoritative, Truncated, RecursionDesired, RecursionAvailableVersione leggibile dei flag sopra
13ResponseCodeNOERROR, NXDOMAIN, SERVFAIL, …Report errori, ricerca di fallimenti di risoluzione
14QuestionTypeTipo di record: A, AAAA, MX, PTR, TXT, …Il volume di TXT è un classico indicatore di tunneling
15QuestionNameNome interrogato come FQDN normaleMatching threat-intel, report top-domain
16InformationTesto libero per voci Event / Note; per Packet la riga header dettagli TCP/UDPLettura messaggi server
17DetailsRappresentazione JSON di un blocco dettaglio Packet; vuoto altrimentiIspezione completa del pacchetto senza tornare al log grezzo
18ComputerNameServer sorgente, da -ComputerNamePermette di attribuire dataset multi-server

Due cose da tenere a mente:

  • Non tutte le colonne sono compilate per ogni riga. Solo le voci Packet hanno IP client, nome della query e codice di risposta. Le righe Note e Event contengono il testo in Information e lasciano vuote le colonne del protocollo. Progetta di conseguenza lo schema del database e i filtri della dashboard.
  • ComputerName è sempre l’ultima colonna, anche se non usi -ComputerName. In quel caso è semplicemente vuota. Questo mantiene l’impaginazione identica su tutti i server così puoi concatenare file da molti server DNS senza dover rimappare colonne.

La colonna Dettagli

I blocchi dettaglio appaiono solo se il server DNS è configurato per registrare i dettagli completi dei pacchetti. Quando esistono, il parser li converte in un singolo valore JSON così la riga resta una sola:

{
  "Socket": "848",
  "Remote": "addr 10.10.0.11, port 60580",
  "Buflength": "0x10000 (65536)",
  "Message": {
    "XID": "0x0001",
    "OPCODE": "0 (QUERY)",
    "RCODE": "0 (NOERROR)",
    "QUESTION": [ { "Name": "berlin.de", "QTYPE": "A (1)", "QCLASS": "1" } ],
    "ANSWER": []
  }
}

Analizzare questi blocchi richiede tempo e rende il CSV molto più grande. Se non ti servono, usa -NoDetailsParsing — la colonna resta presente ma vuota, e la conversione è più veloce. Vedi Performance.

I file di statistiche

Le statistiche sono aggregati giornalieri. Usale quando vuoi una tendenza o un riepilogo e non vuoi spostare l’intero set di record — sono di gran lunga più piccoli del file dati.

Statistiche per contesto (*_Statistic.csv)

Risponde a: quanta attività di che tipo è avvenuta ogni giorno?

Date;Context;Count;ComputerName
2026-01-20;Event;2;dc01
2026-01-20;Note;2;dc01
2026-01-20;Packet;12;dc01
ColonnaSignificato
DateGiorno, sempre yyyy-MM-dd
ContextNome del contesto (Packet, Event, Note, …)
CountNumero di record di quel contesto in quel giorno
ComputerNameServer sorgente

File di esempio: en-US WithComputerName, en-US NoComputerName, de-DE WithComputerName, de-DE NoComputerName

Statistiche pacchetti (*_PacketStatistic.csv)

Risponde a: chi ha interrogato cosa, quanto spesso, ogni giorno?

Date;ClientIP;Protocol;Direction;QuestionType;Count;ComputerName
2026-01-20;10.0.0.1;UDP;Rcv;A;3;dc01
2026-01-20;10.0.0.1;UDP;Snd;A;3;dc01
2026-01-20;10.0.0.2;UDP;Rcv;A;3;dc01
ColonnaSignificato
DateGiorno, sempre yyyy-MM-dd
ClientIPHost che ha fatto la query
ProtocolUDP o TCP
DirectionRcv o Snd
QuestionTypeTipo di record DNS
CountNumero di pacchetti corrispondenti in quel giorno
ComputerNameServer sorgente

File di esempio: en-US WithComputerName, en-US NoComputerName, de-DE WithComputerName, de-DE NoComputerName

Delimitatore e formato data

Entrambi i tipi di output rispettano -Delimiter (default ;) e -OutputCulture. Per tutto ciò che sarà importato da una macchina, scrivi timestamp in formato ISO-like:

Convert-DNSDebugLogFile -InputFile "C:\Logs\dns.log" -OutputCulture 'sv-SE'

Questo produce 2026-01-20 23:00:16, che SQL Server, Power BI e pandas leggono senza bisogno di indicazioni sul formato. Dettagli in Parametri e Opzioni.

3 - Parametri e Opzioni

Cosa cambia effettivamente ogni opzione di Convert-DNSDebugLogFile, quando serve, e le trappole in cui è facile cadere.

Questa pagina spiega le opzioni in modo semplice e nell’ordine in cui tipicamente ti serviranno. È una guida, non una specifica — la lista autorevole e sempre aggiornata dei parametri si trova nel riferimento comandi e in:

Get-Help Convert-DNSDebugLogFile -Full

La versione breve

Convert-DNSDebugLogFile -InputFile "C:\Logs\dns.log"

Questa singola riga ti dà già un comportamento sensato: sia i file dati che quelli statistici, delimitatore punto e virgola, formato data della tua macchina, validazione dell’intestazione attiva, log sorgente intatto. Tutto il resto è fine-tuning.

OpzioneDefaultCambiala quando
-InputFile(obbligatorio)sempre
-OutputFilepercorso input con .csvvuoi l’output da un’altra parte
-Delimiter;il tuo consumatore si aspetta virgola, tab o pipe
-ComputerNamevuotounisci log da più server
-OutputTypeBothvuoi solo dati o solo riepiloghi
-ContextFilterAllti interessa solo il traffico DNS reale
-InputCulturecultura correnteil log proviene da un server con altra localizzazione
-OutputCulturecultura correnteuna macchina leggerà il CSV
-NoDetailsParsingspentoconta più la velocità che i dettagli dei pacchetti
-CompressOutputspentoarchivi o trasferisci i risultati
-RemoveSourceFilespentopulizia programmata, e ti fidi dell’output
-SkipHeaderValidationspentoil file è valido ma l’intestazione è insolita

Input e output

-InputFile

Percorso del log da convertire. Accetta un array e input da pipeline — ecco perché funziona così:

Get-ChildItem "C:\Administration\Logs\DNSServer\*.log" | Convert-DNSDebugLogFile

Get-ChildItem emette oggetti con la proprietà FullName, e -InputFile la accetta per nome proprietà (gli alias includono FullName, Path, FilePath). Non serve ForEach-Object.

Funzionano sia percorsi locali che SMB/UNC:

Convert-DNSDebugLogFile -InputFile "\\dc01\C$\Administration\Logs\DNSServer\dns.log"

Il comando può anche aprire un log che il DNS Server ha attualmente aperto. Vedi log attivi più avanti prima di affidarti a questo.

-OutputFile

Se non lo specifichi, il CSV viene creato accanto al file di input, stesso nome base, estensione .csv. Se lo usi, controlli la destinazione.

-Delimiter

Il default è punto e virgola, perché nelle localizzazioni dove la virgola è il separatore decimale è quello che Excel si aspetta. Usa -Delimiter "," per strumenti e database che assumono valori separati da virgola classici, o -Delimiter "`t" per tabulazione.

Qualunque valore scegli, usa lo stesso lato importazione. Un disallineamento è la causa numero uno di “tutto finito in una colonna”.

Etichettatura e filtraggio

-ComputerName

Compila la colonna ComputerName. La colonna esiste comunque; questa opzione le assegna un valore.

Convert-DNSDebugLogFile -InputFile "C:\Logs\dns.log" -ComputerName $env:COMPUTERNAME

Impostalo sempre quando più server alimentano un dataset — altrimenti non potrai sapere da quale DC proviene una riga.

-OutputType

  • CSV — solo file dati
  • Statistic — solo i due file aggregati, niente dati a livello di riga
  • Both — tutti e tre i file (default)

Statistic è l’opzione veloce e leggera quando ti servono solo tendenze giornaliere. CSV è giusto quando un sistema a valle fa la sua aggregazione.

-ContextFilter

Un log di debug DNS mescola traffico query reale con chiacchiere interne al server. -ContextFilter decide cosa rimane nell’output.

# solo traffico DNS reale
Convert-DNSDebugLogFile -InputFile "C:\Logs\dns.log" -ContextFilter Packet

# traffico più eventi server, ma niente note diagnostiche
Convert-DNSDebugLogFile -InputFile "C:\Logs\dns.log" -ContextFilter Packet, Event
ValoreContiene
Alltutto (default)
Packetquery e risposte DNS — i dati che la maggior parte delle analisi richiede
Eventeventi server, es. “Il server DNS è stato avviato”
Notenote diagnostiche e avvisi, es. errori di socket

Altri tipi di contesto (DSPoll, Init, Lookup, Recurse, Remote, Tombstone) appaiono sotto All.

Filtrare solo su Event o Note popola solo DateTime, ThreadId, Context e Information — le colonne protocollo restano vuote perché quelle voci non contengono quell’informazione.

-ContextFilter Packet è la scelta usuale per pipeline di sicurezza e reportistica: elimina il rumore e riduce sensibilmente l’output.

Log internazionali

Il DNS Server scrive i timestamp nella localizzazione Windows della macchina su cui gira. Un DC tedesco scrive 20.01.2026 23:00:16; un server USA scrive 1/20/2026 11:00:16 PM. Se la localizzazione della tua workstation è diversa da quella del server, il parsing va storto — o peggio, scambia silenziosamente giorno e mese.

-InputCulture

Dì al parser quale localizzazione usa il log sorgente:

Convert-DNSDebugLogFile -InputFile "C:\Logs\dns-berlin.log" -InputCulture 'de-DE'
CulturaFormato timestamp log
de-DEDD.MM.YYYY HH:MM:SS
en-USM/D/YYYY H:MM:SS AM/PM
en-GBDD/MM/YYYY HH:MM:SS
sv-SEYYYY-MM-DD HH:MM:SS

Il default è la cultura della sessione che esegue il comando. In un ambiente con localizzazioni miste, impostalo esplicitamente invece di affidarti al default — e ricorda che un’attività schedulata che gira come SYSTEM potrebbe non avere la cultura con cui hai testato interattivamente.

-OutputCulture

Controlla come i timestamp vengono scritti nel CSV:

# output in stile ISO che SQL Server, Power BI e pandas capiscono tutti
Convert-DNSDebugLogFile -InputFile "C:\Logs\dns.log" -OutputCulture 'sv-SE'

# stesso effetto, cultura invariata esplicita
Convert-DNSDebugLogFile -InputFile "C:\Logs\dns.log" `
    -OutputCulture ([System.Globalization.CultureInfo]::InvariantCulture)

Regola pratica: se un umano apre il file in Excel, usa la cultura locale. Se lo legge una macchina, usa sv-SE o cultura invariata e non preoccuparti delle impostazioni regionali all’importazione.

I due parametri sono indipendenti — puoi leggere un log svedese e scrivere output formattato USA.

Velocità e spazio

-NoDetailsParsing

Se il DNS Server registra dettagli completi dei pacchetti, il parser trasforma ogni blocco di dettaglio in JSON nella colonna Details. È utile, ma è anche la parte più costosa e gonfia il CSV.

Convert-DNSDebugLogFile -InputFile "C:\Logs\dns.log" -NoDetailsParsing

La colonna resta presente ma vuota; la riga di intestazione dettaglio TCP/UDP è ancora disponibile in Information. Su log ricchi di blocchi dettaglio questo può ridurre il tempo di elaborazione del 30–50 %. Usalo quando bastano le informazioni a livello di query.

-CompressOutput

Comprimi i file CSV generati e cancella quelli non compressi. dns.log produce dns.zip invece di dns.csv.

Convert-DNSDebugLogFile -InputFile "C:\Logs\dns.log" -CompressOutput

CSV di questo tipo tipicamente si comprimono del 90% o più, quindi è un risparmio di spazio quasi gratuito per archivi e trasferimenti di file in rete.

-RemoveSourceFile

Cancella il file .log sorgente dopo una conversione riuscita — il log viene rimosso solo se tutti i file di output sono stati creati.

Convert-DNSDebugLogFile -InputFile "C:\Logs\dns.log" -CompressOutput -RemoveSourceFile

Reti di sicurezza

-SkipHeaderValidation

Di default il comando verifica che il file sia davvero un log di debug DNS Server prima di analizzarlo. Questo evita l’errore classico di puntare il lavoro alla cartella sbagliata.

Disattivalo solo per casi davvero insoliti: log modificati a mano, estratti pre-filtrati, formati personalizzati. Lascialo attivo altrove — è economico e ti protegge da errori di battitura e da montagne di righe inutili.

-WhatIf e -Confirm

Il comando supporta entrambi. -WhatIf è il modo giusto per vedere cosa toccherebbe un nuovo lavoro batch:

Get-ChildItem "C:\Administration\Logs\DNSServer\*.log" |
    Convert-DNSDebugLogFile -RemoveSourceFile -WhatIf

-Confirm chiede conferma prima di processare ogni file, prima di cancellare un file sorgente e prima di sovrascrivere output esistenti.

Log attivi

Convert-DNSDebugLogFile può leggere un file che il DNS Server ha aperto. Utile per uno sguardo ad hoc a cosa succede in questo momento.

Metterlo insieme

Una tipica invocazione di produzione su un domain controller:

Get-ChildItem "C:\Administration\Logs\DNSServer\*.log" |
    Sort-Object LastWriteTime -Descending |
    Select-Object -Skip 1 |
    Convert-DNSDebugLogFile `
        -ComputerName $env:COMPUTERNAME `
        -Delimiter ';' `
        -OutputType Both `
        -ContextFilter Packet `
        -OutputCulture 'sv-SE' `
        -CompressOutput

Si legge così: prendi ogni log ruotato tranne quello attivo, tieni solo il traffico DNS, etichetta ogni riga con il nome del server, scrivi timestamp leggibili da macchina, e lascia archivi compressi. La versione completa per attività schedulate e Group Policy è nell’esempio di raccolta guidata da GPO.

4 - Prestazioni

Come il parser gestisce log da 100 MB senza consumare tutta la memoria del server, e cosa puoi fare per mantenere le conversioni veloci.

I log di debug DNS su un controller di dominio molto trafficato sono grandi. Convert-DNSDebugLogFile è stato progettato proprio per questo caso: è stato testato con log da 100 MB e oltre, e li elabora in pochi minuti su hardware server ordinario.

Perché è veloce

Non devi sapere nulla di tutto questo per usare il modulo, ma spiega il comportamento che osserverai.

TecnicaEffetto che noterai
StreamReader / StreamWriter con buffer da 64 KBIl file viene letto e scritto a blocchi invece che con un unico grande Get-Content
Streaming, singolo passaggioL’uso di memoria resta più o meno costante indipendentemente dalla dimensione del log
Operazioni su stringhe (.Substring(), .IndexOf()) invece di espressioni regolariMolto meno CPU per riga, e ci sono milioni di righe
CSV scritto a mano invece di Export-CsvNessun overhead di pipeline oggetti per ogni record
Aggregazione basata su Hashtable per le statisticheI riepiloghi costano quasi nulla durante lo stesso passaggio

La conseguenza importante: l’intero log non viene mai caricato in memoria. Un log da 500 MB non richiede 500 MB di RAM. Questa è la differenza tra il modulo e l’approccio “leggi il file, dividilo, crea oggetti” che la maggior parte degli script fatti in casa usa — quell’approccio funziona bene su un campione da 5 MB ma fallisce su un DC reale.

Come ottenere il massimo da una conversione

Converti i chunk ruotati, non un unico file gigante

Configura il server DNS per far ruotare il log a una dimensione gestibile — da 50 a 200 MB è un buon intervallo. Diversi file medi si convertono in tempi prevedibili e permettono a un job schedulato di finire entro la sua finestra. Un file che cresce sempre invece no.

La rotazione ti dà anche file chiusi con cui lavorare, che è quello che vuoi comunque:

Get-ChildItem "C:\Administration\Logs\DNSServer\*.log" |
    Sort-Object LastWriteTime -Descending |
    Select-Object -Skip 1 |
    Convert-DNSDebugLogFile -ComputerName $env:COMPUTERNAME

Salta il parsing dei dettagli se non ti serve

Se il server DNS scrive dettagli completi dei pacchetti, trasformare quei blocchi in JSON è la parte più costosa della conversione.

Convert-DNSDebugLogFile -InputFile "C:\Logs\dns.log" -NoDetailsParsing

Aspettati esecuzioni dal 30 al 50% più veloci su log che contengono molti blocchi di dettaglio, più un CSV molto più piccolo. Otterrai comunque i dati a livello di query e la riga di intestazione TCP/UDP in Information. Vedi Parametri e Opzioni.

Filtra presto

-ContextFilter Packet scarta note ed eventi del server prima che vengano scritti. Meno output significa meno I/O, file più piccoli e meno lavoro a valle.

Chiedi solo ciò che ti serve

-OutputType Statistic salta completamente la scrittura del CSV a livello di riga. Se la tua dashboard mostra solo conteggi giornalieri, questa è di gran lunga l’opzione più economica.

Converti localmente, sposta i risultati

Il modulo legge percorsi SMB/UNC, ma trasferire un log grezzo da 200 MB in rete per analizzarlo centralmente è il modo più lento. Converti sul server DNS, poi sposta il CSV (compresso) — di solito è un decimo dei byte. Questo è il design dietro l’esempio di raccolta guidata da GPO.

Comprimi per trasferimento e archivio

Convert-DNSDebugLogFile -InputFile "C:\Logs\dns.log" -CompressOutput

Un CSV di questa forma tipicamente si riduce del 90% o più. La compressione costa un po’ di CPU alla fine della conversione e risparmia molto spazio su disco e rete dopo.

Quando una conversione è più lenta del previsto

Controlla questi punti in ordine:

  1. Disco, non CPU. La conversione è intensiva in I/O. Un log su un volume molto occupato, o letto su un collegamento lento, domina il tempo di esecuzione.
  2. Blocchi di dettaglio. Se il log contiene dettagli completi dei pacchetti e non hai usato -NoDetailsParsing, lì va il tempo.
  3. Dimensione del file. Un singolo log multi-gigabyte richiederà comunque tempo. Risolvi con la rotazione, non con i parametri.
  4. Antivirus. La scansione in tempo reale sia del log sorgente che del CSV generato può raddoppiare il costo effettivo di I/O. Un’esclusione per la cartella dei log è una misura comune e ragionevole.
  5. Pressione sulla memoria. Il modulo usa lo streaming, quindi non dovrebbe essere la causa — ma un server già in swapping rallenterà tutto.

Altri sintomi e soluzioni sono raccolti in Risoluzione dei problemi.

5 - Integrazione con Strumenti di Analisi

Come importare il CSV convertito in Excel, Power BI, SQL Server, un SIEM o un notebook Python — inclusi i settaggi di delimitatore e data che fanno funzionare tutto al primo tentativo.

Il senso di convertire un log di debug DNS è ciò che succede dopo. CSV è stato scelto perché tutti lo leggono — ma “tutti leggono CSV” nasconde due impostazioni che decidono se l’importazione è indolore o un pomeriggio di tentativi.

Due impostazioni che decidono tutto

Delimitatore. Il valore predefinito è ;. Lascialo così per Excel nelle località che usano la virgola come separatore decimale. Passa a , per la maggior parte dei database e degli strumenti di data science. Qualunque cosa tu scelga, comunica la stessa cosa al lato importazione.

Formato data. -OutputCulture controlla come vengono scritti i timestamp. Per tutto ciò che viene letto da una macchina, usa sv-SE (o cultura invariata) così che DateTime venga scritto come 2026-01-20 23:00:16:

Convert-DNSDebugLogFile -InputFile "C:\Logs\dns.log" -OutputCulture 'sv-SE'

Ogni consumatore qui sotto capisce quel formato senza bisogno di indicazioni. L’output specifico della località come 20.01.2026 verrà importato come testo o, peggio, interpretato male come mese/giorno.

Microsoft Excel

Il modo più veloce per dare un’occhiata a un singolo log convertito.

  • Con il delimitatore predefinito ; e una località che lo aspetta, un doppio clic apre il file con le colonne corrette.
  • Se tutto finisce nella colonna A, il delimitatore non corrisponde all’impostazione di Excel. Rilancia con -Delimiter "," oppure importa tramite Dati → Da testo/CSV e scegli il delimitatore lì.
  • Trasforma l’intervallo in tabella (Ctrl+T) e crea una tabella pivot su ClientIP, QuestionName o QuestionType. Top client e top domini in circa un minuto.
  • Per più di qualche centinaio di migliaia di righe, usa Power Query o una delle altre opzioni sotto.

I file *_Statistic.csv e *_PacketStatistic.csv sono di solito i migliori per Excel — sono pre-aggregati e rimangono piccoli. Vedi Formati di Output.

Power BI

Importa i file CSV e costruisci dashboard per attività DNS, top client, trend delle query e tassi di errore.

  • Punta Power Query alla cartella che contiene i file convertiti invece che a un singolo file. La struttura è identica tra server e giorni, quindi i file si aggiungono semplicemente.
  • La colonna ComputerName rende possibile un report multi-server — imposta -ComputerName durante la conversione o non potrai filtrare per server.
  • ResponseCode e QuestionType sono slicer naturali; DateTime diventa l’asse temporale.
  • Alimentare Power BI con *_PacketStatistic.csv invece del file completo mantiene il modello piccolo quando ti servono solo i trend giornalieri.

Database SQL

Carica in blocco il CSV in SQL Server, PostgreSQL o qualsiasi altro database SQL, per conservazione a lungo termine e query ripetibili.

Una guida pronta all’uso — definizione tabella, conversione, import con SqlBulkCopy e una query di rilevamento per attività sospette TXT — è documentata in Security Analysis Workflow with SQL Server.

Punti da pianificare prima del primo caricamento:

  • Usa -OutputCulture 'sv-SE' così i timestamp finiscono in una colonna datetime2 senza trucchi di conversione.
  • Information e Details possono essere lunghi; assegna loro nvarchar(max).
  • Indicizza ciò che interroghi davvero — tipicamente DateTime, ClientIP e QuestionName.
  • Mantieni -ComputerName valorizzato così le righe restano attribuibili dopo la fusione.

Sistemi SIEM

Splunk, Elastic, Sentinel e piattaforme simili importano il CSV per correlare con altra telemetria di sicurezza e per gli alert.

  • Invia l’output compresso (-CompressOutput) — è circa un decimo della dimensione e la maggior parte dei collector lo decomprime da sola.
  • Definisci la mappatura dei campi una volta sola; la struttura delle colonne non cambia mai tra esecuzioni o server, inclusa la colonna ComputerName sempre presente alla fine.
  • Fai deduplicare il collector, oppure archivia i file .log processati. Un job di conversione che rielabora gli stessi log ruotati rimanderà altrimenti righe identiche.
  • -ContextFilter Packet mantiene basso il volume di ingestione (e il costo della licenza) quando le note del server non fanno parte dei tuoi casi d’uso.

Python, R e strumenti di data science

L’output strutturato è pronto per rilevamento anomalie, baseline e analisi personalizzate.

import pandas as pd

df = pd.read_csv(
    r"C:\Administration\Logs\DNSServer\dns.csv",
    sep=";",
    parse_dates=["DateTime"],
)

# top 20 nomi interrogati, solo query
top = (
    df[df["Direction"] == "Rcv"]
    .groupby("QuestionName")
    .size()
    .sort_values(ascending=False)
    .head(20)
)
print(top)

parse_dates funziona subito se hai esportato con -OutputCulture 'sv-SE'. Da qui, pandas, scikit-learn o R gestiscono clustering, stagionalità e rilevamento outlier come al solito.

Restare in PowerShell

Non devi uscire da PowerShell per una risposta veloce:

$dns = Import-Csv "C:\Administration\Logs\DNSServer\dns.csv" -Delimiter ';'

# client più rumorosi
$dns | Where-Object Direction -eq 'Rcv' |
    Group-Object ClientIP |
    Sort-Object Count -Descending |
    Select-Object -First 10 Count, Name

# lookup falliti
$dns | Where-Object ResponseCode -eq 'NXDOMAIN' |
    Group-Object QuestionName |
    Sort-Object Count -Descending |
    Select-Object -First 10 Count, Name

Import-Csv legge tutto il file in memoria, quindi va bene per un blocco ruotato ma non per un export di più gigabyte — per quello ci sono i database e i percorsi SIEM.

6 - Pratiche Operative Consigliate

Cosa fare bene prima di lasciare che una conversione di log DNS venga eseguita in modo automatico sui controller di dominio di produzione.

Convertire un log manualmente è facile. Farlo ogni notte su ogni controller di dominio, per anni, senza che nessuno lo controlli, è la parte che richiede un po’ di progettazione. Questi sono i punti che contano nella pratica.

1. Converti i log ruotati, non quello attivo

Abilita il rollover dei log sul server DNS e converti solo i file chiusi. Il modulo può leggere il log su cui il DNS Server sta attualmente scrivendo, ma quel file cambia durante la conversione: le voci più recenti potrebbero mancare e l’ultima riga potrebbe essere troncata. Due esecuzioni producono due risultati diversi.

Lo schema standard salta il file più recente:

Get-ChildItem "C:\Administration\Logs\DNSServer\*.log" |
    Sort-Object LastWriteTime -Descending |
    Select-Object -Skip 1 |
    Convert-DNSDebugLogFile -ComputerName $env:COMPUTERNAME

Un compromesso da tenere a mente: su un server a basso volume, il rollover può richiedere più di un giorno, quindi i dati del giorno corrente restano non convertiti finché il file non ruota. Dimensiona la soglia di rollover di conseguenza.

2. Pianificalo e assegna al job un’identità che funzioni

Task Scheduler è la soluzione abituale — una frequenza giornaliera è un buon default. Un’implementazione completa tramite Group Policy per i controller di dominio è documentata nell’esempio di raccolta guidata da GPO, e un task standalone nell’esempio di Scheduled Task.

Tre cose creano problemi qui:

  • Rilevamento del modulo. Un task che gira come SYSTEM con -NoProfile vede solo i percorsi dei moduli a livello macchina. Installa il modulo a livello macchina o aggiungi un Import-Module esplicito all’azione del task.
  • Localizzazione. L’account che esegue il task potrebbe non avere la stessa localizzazione con cui hai testato interattivamente. Imposta esplicitamente -InputCulture e -OutputCulture invece di affidarti al default.
  • Accesso di rete. Se la sorgente o la destinazione è un percorso UNC, SYSTEM si autentica come account computer. Concedi i permessi di condivisione e NTFS all’account computer (o al gruppo Domain Controllers), oppure esegui il task con un account di servizio dedicato.

3. Ruota a una dimensione che puoi gestire

50–200 MB per file mantiene le conversioni prevedibili e permette a un job notturno di finire entro la finestra prevista. Un file che cresce all’infinito alla fine non ce la fa. Vedi Performance.

4. Valida i primi output prima di automatizzare

Esegui la conversione manualmente su due o tre log reali e apri effettivamente il CSV:

  • Le timestamp sono corrette — non invertite giorno/mese? (Se lo sono, imposta -InputCulture.)
  • Il delimitatore corrisponde a quello che il tuo consumatore si aspetta?
  • ComputerName è valorizzato?
  • I contesti di cui hai bisogno sono presenti, e quelli inutili filtrati?

-WhatIf ti mostra quali file un batch toccherebbe prima di toccarli:

Get-ChildItem "C:\Administration\Logs\DNSServer\*.log" |
    Convert-DNSDebugLogFile -RemoveSourceFile -WhatIf

5. Decidi cosa fare con i log processati

Un job che semplicemente converte “tutti i log tranne il più recente” rielaborerà gli stessi file ogni notte. È robusto e semplice, ma sovrascrive gli output e può inserire righe duplicate in chi li consuma.

Scegli una delle seguenti opzioni:

  • sposta i file .log processati in una cartella di archivio
  • cancellali con -RemoveSourceFile una volta che ti fidi della pipeline
  • fai deduplicare il collector a valle

Qualunque scelta tu faccia, annotala — è il dettaglio che confonde il prossimo amministratore.

6. Pianifica spazio e conservazione

La compressione (-CompressOutput) di solito riduce il CSV del 90% o più, ma il volume si accumula comunque. Stima in base al tuo reale tasso di query e all’obbligo di conservazione, e imposta una data di fine per i dati invece di lasciarli crescere indefinitamente.

-OutputType Statistic vale la pena considerarlo per conservazioni lunghe: i rollup giornalieri sono piccoli e spesso rispondono alle domande di trend per cui si tenevano i dati a livello di riga.

7. Tratta l’output come sensibile

I log DNS analizzati descrivono la tua struttura interna dei nomi e chi ha cercato cosa. Questo è più rivelatore della maggior parte dei log infrastrutturali e, a seconda della tua giurisdizione, può essere considerato dato personale.

  • Limita i permessi NTFS e di condivisione sulle cartelle di output.
  • Non lasciare i CSV su una condivisione generica “temporaneamente”.
  • Includi i dati dei log DNS nella tua policy di conservazione e cancellazione, non solo nella policy di backup.
  • L’output compresso è più piccolo, non protetto — usa crittografia o controllo accessi dove serve.

8. Mantieni attiva la validazione dell’intestazione

Il controllo predefinito che verifica che un file sia davvero un log di debug DNS non costa nulla e previene che un percorso digitato male produca migliaia di righe senza senso. Usa -SkipHeaderValidation solo per formati davvero insoliti — e nota che il comando rifiuta di combinarlo con -RemoveSourceFile proprio per questo motivo.

9. Monitora il job, non solo il server

Una conversione non sorvegliata che si ferma silenziosamente è peggio di nessuna conversione, perché il gap si nota solo quando qualcuno ha bisogno dei dati.

  • Controlla l’output di errore non nullo; l’implementazione di riferimento GPO genera un errore quando $Error.Count -gt 0 così il task segnala il fallimento.
  • Allerta sul codice risultato dell’ultimo task schedulato, non solo sull’esistenza del task.
  • Verifica che i file di output compaiano effettivamente con timestamp recenti.
  • Controlla lo spazio libero su disco sia sul volume dei log che sulla destinazione di output.

Cause comuni di un’esecuzione fallita — accesso negato, log corrotti, intestazioni non valide — sono trattate in Troubleshooting.

10. Documenta il flusso di lavoro

Dove vengono scritti i log, quando gira il job, quali parametri usa, dove va l’output, chi lo consuma e per quanto tempo viene conservato. Sei righe nella tua wiki operativa. È ciò che rende la configurazione verificabile e trasferibile.

7 - Risoluzione dei problemi

Sintomi che potresti incontrare durante la conversione dei log di debug DNS, cosa li causa e come risolverli.

“Il file non è un file di log di debug DNS valido”

Il controllo dell’intestazione ha rifiutato l’input. Di solito il percorso è semplicemente errato — un file .log nella stessa cartella che non è il log di debug DNS, o un file che contiene solo un’intestazione ruotata.

Segui questi passaggi:

  1. Apri il file. Un log di debug DNS inizia con una riga di intestazione come Message logging started at … e continua con voci di query con timestamp.

  2. Conferma che il logging di debug DNS sia effettivamente abilitato e stia scrivendo nel percorso che ti aspetti:

    Get-DnsServerDiagnostics | Select-Object Enable, LogFilePath, MaxMBFileSize
    
  3. Se il file è davvero un log DNS ma l’intestazione è insolita — modificata a mano, pre-filtrata, esportazione personalizzata — bypassa il controllo:

    Convert-DNSDebugLogFile -InputFile "C:\Logs\odd.log" -SkipHeaderValidation
    

Mantieni la validazione abilitata ovunque altrove. Nota che -SkipHeaderValidation non può essere combinato con -RemoveSourceFile, quindi un file non verificato non può mai essere cancellato dalla conversione.

Il file di output è vuoto o ha molte meno righe del previsto

Controlla, in questo ordine:

  • Il log contiene voci di query? Un log appena ruotato può contenere solo un’intestazione se non sono ancora avvenute query.
  • È in uso un -ContextFilter? -ContextFilter Packet rimuove per design le voci Event e Note. Se hai filtrato su Event o Note, la maggior parte delle colonne sarà vuota — quei tipi di voci contengono solo DateTime, ThreadId, Context e Information.
  • Il log di origine era attivo? Un file su cui DNS Server sta ancora scrivendo può cambiare durante la conversione; le voci più recenti potrebbero mancare e l’ultima riga potrebbe essere troncata. Converti un log ruotato e chiuso quando ti serve un output completo.
  • Il file è corrotto o troncato? Controlla la fine del log per una riga scritta a metà.

Le date sono sbagliate, spostate o giorno e mese sono invertiti

Il log è stato scritto da un server con una locale Windows diversa dalla sessione che esegue la conversione. 20.01.2026 e 01/20/2026 descrivono lo stesso momento, ma solo se entrambe le parti concordano sul formato.

# il log proviene da un server tedesco
Convert-DNSDebugLogFile -InputFile "C:\Logs\dns-berlin.log" -InputCulture 'de-DE'

Imposta -InputCulture esplicitamente nei lavori schedulati invece di affidarti alla cultura dell’account che li esegue. Se l’output deve essere leggibile dalla macchina, aggiungi -OutputCulture 'sv-SE'. Dettagli in Parametri e Opzioni.

Tutto finisce in una colonna dopo l’importazione

Disallineamento del delimitatore. Il modulo scrive ; per default; il tuo consumatore si aspettava , (o viceversa).

Riesegui la conversione con il delimitatore che vuole il consumatore:

Convert-DNSDebugLogFile -InputFile "C:\Logs\dns.log" -Delimiter ","

…oppure indica all’importatore quale delimitatore usa il file — in Excel tramite Dati → Da testo/CSV, in PowerShell tramite Import-Csv -Delimiter ';'.

“Accesso negato”

  • La cartella del log DNS di solito richiede diritti amministrativi. Avvia PowerShell elevato, o esegui il task schedulato con un account che ha accesso.
  • Controlla anche i permessi di scrittura sulla cartella di output, non solo quelli di lettura sul log.
  • Per percorsi SMB/UNC: un task in esecuzione come SYSTEM si autentica in rete come account computer. Concedi i diritti di condivisione e NTFS a quell’account computer (o al gruppo Domain Controllers), oppure usa un account di servizio dedicato.
  • Se -RemoveSourceFile fallisce alla fine di una esecuzione altrimenti riuscita, l’account può leggere il log ma non cancellarlo.

L’elaborazione è molto lenta

  1. Prima il disco — la conversione è limitata dall’I/O. Un volume occupato o un percorso di rete lento dominano i tempi di esecuzione.
  2. Usa -NoDetailsParsing se non ti serve il JSON dei dettagli pacchetto; su log con molti dettagli questo fa risparmiare il 30–50%.
  3. Usa -ContextFilter Packet per scrivere meno.
  4. Suddividi log enormi con la rotazione del log di DNS Server invece di convertire un unico file gigantesco.
  5. Considera un’esclusione antivirus per la cartella dei log.

Di più in Prestazioni.

L’output compresso è più grande del previsto

I log con contenuti molto diversi — molti domini unici, molti client distinti — si comprimono meno di quelli ripetitivi. È normale. ZIP comunque di solito ottiene una riduzione sostanziale; se non succede, verifica se la colonna Details sta gonfiando il file e se ti serve davvero.

Le statistiche non corrispondono a quanto mi aspettavo

  • Conferma di aver usato -OutputType Both o -OutputType Statistic. Con -OutputType CSV non viene scritto alcun file di statistiche.
  • Count è un totale, non un conteggio distinto. Un client che chiede lo stesso nome 500 volte contribuisce con 500. Questa è la causa più frequente di “quel numero non può essere giusto”.
  • Le statistiche sono raggruppate per giorno. Un log che copre due giorni produce righe per entrambi.
  • Se ComputerName è vuoto nei file di statistiche, -ComputerName non è stato impostato durante la conversione.

Il task schedulato funziona interattivamente ma non come task

Quasi sempre uno di questi tre casi:

  • Modulo non trovato. SYSTEM con -NoProfile vede solo i percorsi dei moduli a livello macchina. Installa il modulo a livello macchina o aggiungi un Import-Module DNSServer.DebugLogParser esplicito all’azione del task.
  • Cultura sbagliata. La locale dell’account del task è diversa dalla tua. Imposta -InputCulture e -OutputCulture esplicitamente.
  • Politica di esecuzione o script non firmato. Allinea il -ExecutionPolicy del task alla tua politica di firma, e sblocca i file copiati da altre fonti.

Esegui manualmente la stessa riga di comando del task nello stesso contesto (per esempio con PsExec come SYSTEM) per riprodurlo.

Segnalare un problema

Se nulla di tutto questo aiuta:

  1. Aggiorna all’ultima versione del modulo e riprova.

  2. Cerca nei GitHub issues lo stesso sintomo.

  3. Raccogli le diagnostiche:

    $PSVersionTable
    Get-Module DNSServer.DebugLogParser -ListAvailable | Select-Object Name, Version, Path
    Get-Culture
    

    più il comando esatto che hai eseguito, il messaggio di errore completo incluso lo stack trace, e — se puoi condividerlo — un piccolo estratto anonimizzato del log che riproduce il problema.

  4. Apri una nuova issue con queste informazioni.

8 - Riferimento ai comandi del modulo

Qui puoi trovare un riferimento per tutti i comandi del modulo. Questo riferimento è pensato per aiutarti a trovare rapidamente il comando di cui hai bisogno e a capire come usarlo efficacemente.

Cliccando su un comando, verrai portato a una pagina dettagliata che fornisce informazioni complete sul comando, inclusi sintassi, parametri, esempi e eventuali note o suggerimenti aggiuntivi per l’uso.

8.1 - Convert-DNSDebugLogFile

SYNOPSIS

Trasforma i log di debug del server DNS di Windows in un formato CSV strutturato per analisi e reportistica.

SYNTAX

__AllParameterSets

Convert-DNSDebugLogFile [-InputFile] <string[]> [[-OutputFile] <string>] [[-Delimiter] <string>]
 [[-ComputerName] <string>] [[-OutputType] <string>] [[-ContextFilter] <string[]>]
 [[-InputCulture] <cultureinfo>] [[-OutputCulture] <cultureinfo>] [-SkipHeaderValidation]
 [-RemoveSourceFile] [-CompressOutput] [-NoDetailsParsing] [-WhatIf] [-Confirm]

ALIASES

Questo cmdlet ha i seguenti alias,

DESCRIPTION

Converte i file di log di debug del server DNS di Windows in dati CSV strutturati che possono essere analizzati in Excel, Power BI, database SQL o strumenti SIEM. Progettato per analisi di sicurezza, monitoraggio delle prestazioni, risoluzione dei problemi e reportistica di conformità.

Il cmdlet analizza i log di debug DNS e scrive un output CSV coerente per l’analisi. L’output CSV contiene 18 colonne, inclusa una colonna Information per testo di eventi/diagnostica, una colonna JSON opzionale Details per i blocchi di dettaglio dei pacchetti, e una colonna ComputerName sempre presente (vuota se non specificata).

CARATTERISTICHE PRINCIPALI:

  • Elaborazione in streaming evita di caricare l’intero file in memoria (adatto per log molto grandi)
  • Parsing ad alte prestazioni ottimizzato per file di grandi dimensioni (oltre 100MB)
  • Delimitatore CSV personalizzabile (default: punto e virgola)
  • Sommari statistici opzionali con metriche aggregate
  • Filtraggio per contesto (Packet, Event, Note e altri contesti) per concentrarsi su tipi specifici di voci di log
  • Parsing e formattazione delle date sensibili alla cultura per server internazionali
  • Supporto pipeline per elaborazione batch di più file
  • Compressione opzionale dei file di output (formato ZIP)
  • Rimozione automatica opzionale dei file sorgente dopo l’elaborazione
  • Validazione dell’intestazione per garantire l’integrità dei dati

FORMATO DI OUTPUT: La colonna ComputerName è sempre inclusa alla fine di ogni record. Se il parametro -ComputerName non è specificato, la colonna sarà vuota. Questo garantisce una struttura di output coerente per scenari di consolidamento multi-server.

PRESTAZIONI: Ottimizzato usando StreamReader/StreamWriter con buffer da 64KB, elaborazione in streaming per gestione efficiente in memoria di file grandi, operazioni su stringhe invece di regex, generazione manuale CSV, e raccolta efficiente di statistiche basata su hashtable.

COMPATIBILITÀ:

  • PowerShell 5.1+ (edizioni Desktop e Core)
  • Windows Server 2016+
  • Formati log DNS Server da 2012 R2 fino al 2025

EXAMPLES

ESEMPIO 1

PS C:\> Convert-DNSDebugLogFile -InputFile "C:\Logs\dns.log"

Converte il log di debug DNS usando le impostazioni predefinite (sia file dati che statistici con delimitatore punto e virgola). Output:

  • C:\Logs\dns.csv
  • C:\Logs\dns_Statistic.csv
  • C:\Logs\dns_PacketStatistic.csv

ESEMPIO 2

PS C:\> Convert-DNSDebugLogFile -InputFile "C:\Logs\dns.log" -OutputType CSV

Genera solo il file dati senza statistiche. Output: C:\Logs\dns.csv

ESEMPIO 3

PS C:\> Convert-DNSDebugLogFile -InputFile "C:\Logs\dns.log" -OutputType Statistic

Genera solo i file statistici con metriche aggregate. Output:

  • C:\Logs\dns_Statistic.csv
  • C:\Logs\dns_PacketStatistic.csv

ESEMPIO 4

PS C:\> Convert-DNSDebugLogFile -InputFile "C:\Logs\dns.log" -OutputFile "C:\Output\parsed.csv"

Converte il log in una posizione di output personalizzata. Output: C:\Output\parsed.csv

ESEMPIO 5

PS C:\> Convert-DNSDebugLogFile -InputFile "C:\Logs\dns.log" -Delimiter "," -ComputerName "DNS01" -OutputType Both

Converte con delimitatore virgola e aggiunge la colonna ComputerName con valore “DNS01”. Output:

  • C:\Logs\dns.csv
  • C:\Logs\dns_Statistic.csv
  • C:\Logs\dns_PacketStatistic.csv

ESEMPIO 6

PS C:\> Get-ChildItem "C:\Logs\*.log" | Convert-DNSDebugLogFile -OutputType Both

Elabora in batch più file di log di debug DNS tramite pipeline. Output: Per ogni file .log, genera file .csv e _statistic.csv

ESEMPIO 7

PS C:\> Convert-DNSDebugLogFile -InputFile "C:\Logs\dns.log" -CompressOutput

Converte e comprime l’output in un archivio ZIP. Output: C:\Logs\dns.zip (contenente dns.csv + file statistici)

ESEMPIO 8

PS C:\> Convert-DNSDebugLogFile -InputFile "C:\Logs\dns.log" -RemoveSourceFile -Verbose

Converte il log e rimuove il file sorgente dopo l’elaborazione riuscita. L’output Verbose conferma la rimozione del file.

ESEMPIO 9

PS C:\> Convert-DNSDebugLogFile -InputFile "C:\Logs\dns.log" -InputCulture 'de-DE' -OutputCulture 'en-US'

Analizza il formato data tedesco (GG.MM.AAAA) e produce output in formato USA (MM/GG/AAAA). Usa quando si elaborano log da server con impostazioni regionali differenti.

ESEMPIO 10

PS C:\> Convert-DNSDebugLogFile -InputFile "C:\Logs\dns.log" -ContextFilter 'Packet'

Converte solo le voci di pacchetti query/response DNS, escludendo EVENT e Note. Usa per focalizzare l’analisi sul traffico DNS reale.

ESEMPIO 11

PS C:\> Convert-DNSDebugLogFile -InputFile "C:\Logs\dns.log" -ContextFilter 'Packet','Event'

Converte sia i pacchetti query/response DNS che gli eventi del server, escludendo Note e altre voci. Usa per analizzare il traffico DNS insieme al contesto degli eventi server.

ESEMPIO 12

PS C:\> Get-ChildItem "C:\Logs\*.log" | Convert-DNSDebugLogFile -RemoveSourceFile -CompressOutput

Archiviazione automatica dei log: elabora tutti i log, comprime l’output e rimuove i file sorgente. Ideale per pipeline di elaborazione log pianificate.

ESEMPIO 13

PS C:\> Convert-DNSDebugLogFile -InputFile "C:\Logs\large-dns.log" -NoDetailsParsing

Elabora un file di log grande con parsing dei dettagli disabilitato per massimizzare le prestazioni. I blocchi di dettaglio PACKET sono saltati, mantenendo vuota la colonna Details. Usa quando si elaborano file molto grandi e non è necessaria un’analisi dettagliata della struttura dei pacchetti.

PARAMETERS

-CompressOutput

Comprimi i file CSV di output in un archivio ZIP dopo la creazione.

Crea un file .zip contenente il/i file CSV generato/i, quindi rimuove i CSV non compressi. Il file ZIP viene creato nella stessa directory del CSV di output con lo stesso nome base.

Vantaggi:

  • Riduce significativamente lo spazio su disco (i file CSV si comprimono tipicamente oltre il 90%)
  • Semplifica la gestione e l’archiviazione dei file
  • Adatto per l’archiviazione a lungo termine

Esempio: l’input ‘dns.log’ genera ‘dns.csv’ compresso in ‘dns.zip’, quindi ‘dns.csv’ viene rimosso.

Type: SwitchParameter
DefaultValue: False
SupportsWildcards: false
Aliases: []
ParameterSets:
- Name: (All)
  Position: Named
  IsRequired: false
  ValueFromPipeline: false
  ValueFromPipelineByPropertyName: false
  ValueFromRemainingArguments: false
DontShow: false
AcceptedValues: []
HelpMessage: ''

-ComputerName

Specifica il valore per la colonna ComputerName nell’output CSV. La colonna ComputerName è sempre presente nell’output - se questo parametro non è specificato, la colonna sarà vuota.

Usalo quando si consolidano log da più server DNS per identificare il server di origine nei dataset combinati.

Nota: NON è un parametro di remoting. Etichetta solo l’output. Se si punta -InputFile a un percorso UNC, il file viene letto da quel percorso (non viene eseguito WinRM/esecuzione remota).

Type: String
DefaultValue: ''
SupportsWildcards: false
Aliases:
- Server
- DNSServer
- HostName
ParameterSets:
- Name: (All)
  Position: 3
  IsRequired: false
  ValueFromPipeline: false
  ValueFromPipelineByPropertyName: false
  ValueFromRemainingArguments: false
DontShow: false
AcceptedValues: []
HelpMessage: ''

-Confirm

Richiede conferma prima di eseguire il cmdlet.

Se specificato, chiede conferma prima di:

  • Elaborare ogni file di log di debug DNS
  • Rimuovere i file sorgente (quando è specificato -RemoveSourceFile)
  • Sovrascrivere file di output esistenti

Utile per elaborazione interattiva quando vuoi controllare quali file vengono processati.

Type: SwitchParameter
DefaultValue: ''
SupportsWildcards: false
Aliases:
- cf
ParameterSets:
- Name: (All)
  Position: Named
  IsRequired: false
  ValueFromPipeline: false
  ValueFromPipelineByPropertyName: false
  ValueFromRemainingArguments: false
DontShow: false
AcceptedValues: []
HelpMessage: ''

-ContextFilter

Filtra quali tipi di voci di log includere nell’output. Accetta uno o più valori.

I log di debug DNS contengono diversi tipi di contesto:

  • PACKET: Informazioni sui pacchetti di query e risposta DNS (dati primari)
  • EVENT: Eventi del server DNS (es. “Il server DNS è stato avviato.”)
  • Note: Note diagnostiche e avvisi (es. errori di socket, stati interni)
  • DSPoll, Init, Lookup, Recurse, Remote, Tombstone: Tipi di contesto aggiuntivi

Valori validi:

  • ‘All’: Include tutti i tipi di contesto (default)
  • ‘Packet’: Include solo le voci PACKET (query/risposte DNS)
  • ‘Event’: Include solo le voci EVENT (eventi server)
  • ‘Note’: Include solo le voci Note (informazioni diagnostiche)
  • Qualsiasi combinazione: Specifica più valori per includere tipi di contesto specifici

Default: All

Esempi:

  • ‘Packet’ filtra solo il traffico DNS
  • ‘Packet’,‘Event’ include sia traffico DNS che eventi server
  • ‘Note’,‘Event’ include note diagnostiche ed eventi server

Nota: Quando si filtra su ‘Event’ o ‘Note’, solo le colonne DateTime, ThreadId, Context e Information conterranno dati. Le altre colonne (Protocol, ClientIP, ecc.) saranno vuote.

Type: String[]
DefaultValue: "@('All')"
SupportsWildcards: false
Aliases: []
ParameterSets:
- Name: (All)
  Position: 5
  IsRequired: false
  ValueFromPipeline: false
  ValueFromPipelineByPropertyName: false
  ValueFromRemainingArguments: false
DontShow: false
AcceptedValues: []
HelpMessage: ''

-Delimiter

Specifica il carattere delimitatore per l’output CSV.

Default: Punto e virgola (;)

Alternative comuni: Virgola (,), Tab (`t), Pipe (|)

Usa il punto e virgola nelle regioni dove la virgola è il separatore decimale (Europa). Usa la virgola per strumenti CSV standard e database che si aspettano valori separati da virgola.

Type: String
DefaultValue: ;
SupportsWildcards: false
Aliases: []
ParameterSets:
- Name: (All)
  Position: 2
  IsRequired: false
  ValueFromPipeline: false
  ValueFromPipelineByPropertyName: false
  ValueFromRemainingArguments: false
DontShow: false
AcceptedValues: []
HelpMessage: ''

-InputCulture

Specifica la cultura/locale da usare per il parsing dei valori data/ora nel log di debug DNS.

I log di debug del server DNS usano il formato data della locale Windows sul server dove il log è stato generato. Usa questo parametro quando si elaborano log da server con impostazioni regionali diverse.

Default: Cultura corrente

Esempi comuni:

  • ‘de-DE’ o ‘de-AT’: formato tedesco (GG.MM.AAAA o GG/MM/AAAA)
  • ’en-US’: formato USA (MM/GG/AAAA con AM/PM)
  • ’en-GB’: formato UK (GG/MM/AAAA con orario 24h)
  • ‘sv-SE’: formato svedese/ISO (AAAA-MM-GG)
Type: CultureInfo
DefaultValue: '[System.Globalization.CultureInfo]::CurrentCulture'
SupportsWildcards: false
Aliases: []
ParameterSets:
- Name: (All)
  Position: 6
  IsRequired: false
  ValueFromPipeline: false
  ValueFromPipelineByPropertyName: false
  ValueFromRemainingArguments: false
DontShow: false
AcceptedValues: []
HelpMessage: ''

-InputFile

Specifica il percorso del file di log di debug DNS da analizzare. Supporta array per elaborare più file.

Accetta input da pipeline da Get-ChildItem o altri cmdlet che producono file.

Type: String[]
DefaultValue: ''
SupportsWildcards: false
Aliases:
- FullName
- FilePath
- InputPath
- File
- Path
ParameterSets:
- Name: (All)
  Position: 0
  IsRequired: true
  ValueFromPipeline: true
  ValueFromPipelineByPropertyName: true
  ValueFromRemainingArguments: false
DontShow: false
AcceptedValues: []
HelpMessage: ''

-NoDetailsParsing

Salta il parsing dei blocchi di dettaglio PACKET in formato JSON strutturato.

Se specificato, i record PACKET con blocchi di dettaglio avranno la linea info TCP/UDP nella colonna Information, ma la colonna Details rimarrà vuota. Questo migliora significativamente le prestazioni di elaborazione per file di log grandi quando non è necessaria un’analisi dettagliata della struttura dei pacchetti.

Usa questo switch quando:

  • Elabori file di log molto grandi (oltre 100MB) e ti servono solo informazioni base sulle query
  • La struttura dettagliata (flag messaggi, sezioni DNS) non è richiesta per l’analisi
  • Vuoi massimizzare la velocità di parsing più che la completezza dei dati

Impatto sulle prestazioni: può migliorare la velocità di elaborazione del 30-50% per log con molti blocchi di dettaglio PACKET.

Type: SwitchParameter
DefaultValue: False
SupportsWildcards: false
Aliases: []
ParameterSets:
- Name: (All)
  Position: Named
  IsRequired: false
  ValueFromPipeline: false
  ValueFromPipelineByPropertyName: false
  ValueFromRemainingArguments: false
DontShow: false
AcceptedValues: []
HelpMessage: ''

-OutputCulture

Specifica la cultura/locale da usare per formattare i valori data/ora nei file CSV di output.

Controlla come i valori DateTime vengono scritti nel CSV. Usa questo parametro quando i file CSV saranno consumati da applicazioni o sistemi con impostazioni regionali specifiche.

Default: Cultura corrente

Esempi comuni:

  • ’en-US’: formato USA (MM/GG/AAAA)
  • ‘de-DE’: formato tedesco (GG.MM.AAAA)
  • ‘sv-SE’ o InvariantCulture: formato ISO (AAAA-MM-GG) per massima compatibilità
Type: CultureInfo
DefaultValue: '[System.Globalization.CultureInfo]::CurrentCulture'
SupportsWildcards: false
Aliases: []
ParameterSets:
- Name: (All)
  Position: 7
  IsRequired: false
  ValueFromPipeline: false
  ValueFromPipelineByPropertyName: false
  ValueFromRemainingArguments: false
DontShow: false
AcceptedValues: []
HelpMessage: ''

-OutputFile

Specifica il percorso per il file CSV di output. Se non specificato, usa il nome del file di input con estensione .csv nella stessa directory del file di input.

Importante: Deve essere un percorso file, non una directory. Se vuoi usare la directory del file di input con un nome personalizzato, specifica il percorso completo incluso il nome file.

Type: String
DefaultValue: ''
SupportsWildcards: false
Aliases:
- Output
- Destination
- OutFile
- OutputPath
ParameterSets:
- Name: (All)
  Position: 1
  IsRequired: false
  ValueFromPipeline: false
  ValueFromPipelineByPropertyName: false
  ValueFromRemainingArguments: false
DontShow: false
AcceptedValues: []
HelpMessage: ''

-OutputType

Specifica il tipo di output da generare.

Valori validi:

  • ‘CSV’: Genera solo il file dati con tutte le voci di log analizzate
  • ‘Statistic’: Genera solo i file statistici con metriche aggregate
  • ‘Both’: Genera sia file dati che statistici (default)

Default: Both

Quando vengono generate le statistiche, si creano due file separati:

  • ‘_Statistic.csv’: conteggi riepilogativi per tipo di contesto per giorno (Data, Contesto, Conteggio, ComputerName)
  • ‘_PacketStatistic.csv’: conteggi dettagliati PACKET per giorno per IP client, protocollo, direzione, e tipo di query (Data, ClientIP, Protocollo, Direzione, TipoDomanda, Conteggio, ComputerName)
Type: String
DefaultValue: Both
SupportsWildcards: false
Aliases: []
ParameterSets:
- Name: (All)
  Position: 4
  IsRequired: false
  ValueFromPipeline: false
  ValueFromPipelineByPropertyName: false
  ValueFromRemainingArguments: false
DontShow: false
AcceptedValues: []
HelpMessage: ''

-RemoveSourceFile

Rimuove il file di log di debug DNS sorgente dopo l’elaborazione riuscita.

Usa questo per pipeline di elaborazione log automatizzate o gestione dello spazio disco. Il file sorgente viene rimosso solo se l’elaborazione termina con successo e tutti i file di output sono creati.

Sicurezza: Non può essere usato con -SkipHeaderValidation per evitare la cancellazione accidentale di file non validi.

Avviso: I file sorgente vengono cancellati definitivamente. Assicurati che i file di output siano validi prima di usare questa opzione.

Type: SwitchParameter
DefaultValue: False
SupportsWildcards: false
Aliases: []
ParameterSets:
- Name: (All)
  Position: Named
  IsRequired: false
  ValueFromPipeline: false
  ValueFromPipelineByPropertyName: false
  ValueFromRemainingArguments: false
DontShow: false
AcceptedValues: []
HelpMessage: ''

-SkipHeaderValidation

Salta il controllo di validazione dell’intestazione del log di debug DNS.

Di default, il cmdlet verifica che i file di input abbiano un’intestazione valida di log di debug DNS Server. Usa questo switch per elaborare file senza validazione, utile per:

  • Formati di log modificati o personalizzati
  • Risoluzione di problemi di validazione
  • Log non standard o pre-elaborati

Avviso: Potrebbe causare errori di elaborazione se il file non è un log DNS valido.

Type: SwitchParameter
DefaultValue: False
SupportsWildcards: false
Aliases: []
ParameterSets:
- Name: (All)
  Position: Named
  IsRequired: false
  ValueFromPipeline: false
  ValueFromPipelineByPropertyName: false
  ValueFromRemainingArguments: false
DontShow: false
AcceptedValues: []
HelpMessage: ''

-WhatIf

Mostra cosa succederebbe se il cmdlet venisse eseguito. Il cmdlet non viene eseguito.

Se specificato, mostra informazioni dettagliate sulle operazioni che verrebbero eseguite senza eseguirle realmente. Utile per:

  • Anteprima dei file che verrebbero processati
  • Verifica dei percorsi dei file di output prima dell’elaborazione
  • Test di script prima dell’esecuzione in produzione
Type: SwitchParameter
DefaultValue: ''
SupportsWildcards: false
Aliases:
- wi
ParameterSets:
- Name: (All)
  Position: Named
  IsRequired: false
  ValueFromPipeline: false
  ValueFromPipelineByPropertyName: false
  ValueFromRemainingArguments: false
DontShow: false
AcceptedValues: []
HelpMessage: ''

CommonParameters

Questo cmdlet supporta i parametri comuni: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutBuffer, -OutVariable, -PipelineVariable, -ProgressAction, -Verbose, -WarningAction, e -WarningVariable. Per maggiori informazioni, vedi about_CommonParameters.

INPUTS

System.String[]

NOTES

Versione : 1.7.2.1 Autore : Andi Bellstedt, Copilot, Patrick Charbonnier (Silent Waters IT Consulting S.L.) Data : 2026-07-24 Parole chiave : Microsoft Windows Server, DNSServer, DNS, DebugLog, LogParser

9 - Esempi di utilizzo

Qui puoi trovare esempi pratici di come utilizzare il modulo in scenari reali. Questi esempi sono pensati per aiutarti a capire come applicare le funzionalità del modulo.

Questi sono esempi con un po’ più di profondità e contesto. Se vuoi solo l’uso dei comandi del modulo, dai un’occhiata al riferimento comandi.

9.1 - Flusso di lavoro per l'analisi della sicurezza con SQL Server

Converti i log di debug DNS in CSV con DNSServer.DebugLogParser, importa il risultato in SQL Server ed esegui una semplice query di rilevamento per attività sospette sui record TXT.

Questo esempio mostra un flusso di lavoro pratico per l’analisi della sicurezza: analizza un log di debug DNS con Convert-DNSDebugLogFile, importa il CSV generato in SQL Server ed esegui una query che evidenzia volumi insolitamente alti di interrogazioni a record TXT.

Per la migliore interoperabilità, questo esempio scrive i timestamp in un formato simile all’ISO usando -OutputCulture 'sv-SE'.

Moduli richiesti

Questo esempio utilizza i seguenti moduli PowerShell:

  • DNSServer.DebugLogParser
  • SqlServer

Installali se necessario:

Install-Module -Name DNSServer.DebugLogParser -Scope CurrentUser
Install-Module -Name SqlServer -Scope CurrentUser

Scenario

Usa questo flusso di lavoro quando vuoi spostare i dati del log di debug DNS analizzati in SQL Server per poter:

  • cercare grandi dataset in modo efficiente
  • costruire query di rilevamento ripetibili
  • correlare attività tra più server DNS
  • conservare dati normalizzati per indagini successive

Output del passaggio di conversione

Convert-DNSDebugLogFile non scrive direttamente in SQL Server. Prima crea un file CSV. Quel file CSV è il dataset importato nel database.

In questo esempio:

  • log di input: C:\Administration\Logs\DNS\dns.log
  • CSV generato: C:\Administration\Logs\DNS\dns.csv
  • tabella di destinazione: dbo.DNSQueries

Creare la tabella di destinazione

Esegui la seguente istruzione una volta in SQL Server per creare la tabella di destinazione.

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;

Convertire il log e importare il CSV

Il seguente esempio PowerShell esegue l’intero flusso di lavoro:

  1. importa i moduli richiesti
  2. converte il log di debug DNS in CSV
  3. carica il CSV generato
  4. importa in blocco le righe in SQL Server
# 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 "Il file CSV generato '$csvPath' non contiene righe."
}

$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()
}

Query per attività sospette sui record TXT

Una volta che i dati sono in SQL Server, puoi cercare i client che effettuano un numero insolitamente alto di query ai record 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;

Se preferisci eseguire la query da PowerShell, usa Invoke-Sqlcmd dal modulo SqlServer:

$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

Perché le query TXT sono interessanti

Volumi elevati di interrogazioni ai record TXT possono valere la pena di essere esaminati perché potrebbero indicare:

  • tunneling DNS
  • esfiltrazione di dati tramite DNS
  • abuso dei record TXT da parte di malware o strumenti
  • client insolitamente rumorosi o mal configurati

Questa query è solo un punto di partenza. In produzione, dovresti regolare la soglia e aggiungere filtri che si adattino al tuo ambiente.

Note operative

  • Import-Csv carica l’intero file in memoria. Per esportazioni di log molto grandi, considera un approccio in streaming invece di costruire un intero DataTable.
  • Mantieni -ComputerName nel passaggio di conversione così i record rimangono attribuibili dopo l’ingestione centralizzata.
  • Usa un delimitatore e una cultura coerenti durante esportazione e importazione.
  • Valida la conservazione, l’indicizzazione e il controllo degli accessi in SQL Server prima di usare questo flusso di lavoro per l’archiviazione a lungo termine.

9.2 - Esempio di Attività Pianificata

Questo esempio mostra come creare un’attività pianificata di Windows che esegue uno script PowerShell per elaborare quotidianamente i log di debug DNS.

Questo script crea un’attività pianificata di Windows che viene eseguita ogni giorno alle 2:00 AM. Importa il modulo ed elabora tutti i file di log nella cartella in cui viene eseguito lo script (in questo esempio “C:\Administration\Logs\DNS”). Il processo comprime l’output in file ZIP e rimuove l’originale per mantenere l’ordine.

$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"

9.3 - Utilizzo pratico in un ambiente di dominio (raccolta e conversione guidate da GPO)

Questo esempio dimostra come implementare un flusso di lavoro guidato da GPO per la raccolta e la conversione dei log di debug DNS sui controller di dominio.

Questo documento illustra un esempio pratico, end-to-end, di esecuzione di DNSServer.DebugLogParser in un ambiente di dominio Active Directory, focalizzato sulla conversione dei log di debug del server DNS di Windows sui controller di dominio.

Questo esempio è accompagnato da un archivio ZIP, che fornisce gli artefatti di policy utilizzati per implementare il flusso di lavoro descritto qui.
Gli artefatti più rilevanti sono il manifest di backup, il report GPO, il Files.xml, lo Set-DNSServerDebugLogging.ps1 e il ScheduledTasks.xml.

Scenario

  • Più controller di dominio (DC) ospitano il ruolo DNS Server.
  • Il logging di debug DNS è abilitato e configurato in modo coerente su ogni DC tramite un’attività pianificata (che scrive i file di log in C:\Administration\Logs\DNSServer).
  • Un processo gestito centralmente converte i log in CSV per:
    • analisi di sicurezza
    • report operativi
    • risoluzione dei problemi
    • conformità/conservazione

Obiettivi

  • Impostazioni di conversione coerenti su tutti i DC
  • Posizione e denominazione dell’output prevedibili
  • Compressione opzionale per ridurre lo spazio di archiviazione
  • Output statistici opzionali per riepiloghi giornalieri rapidi
  • Rischio minimo sul lato host, con considerazioni esplicite su riesecuzione e pulizia

Architettura suggerita

Modello di raccolta: conversione locale + raccolta centrale

  1. Ogni DC scrive i log di debug DNS su disco con rollover abilitato.
  2. Ogni DC converte i file *.log ruotati in un CSV dati e CSV statistici, quindi comprime gli output in *.zip secondo una pianificazione (Utilità di pianificazione).
  3. Gli output sono scritti accanto ai file di log per mantenere semplice la pipeline.
  4. Un server centrale raccoglie gli output *.zip, ad esempio tramite condivisione file, copia pianificata, inoltro SIEM o un collector basato su agente.

Questo modello minimizza le letture di rete di grandi file di log grezzi e mantiene l’analisi vicino ai dati.

Flusso di lavoro GPO

Il flusso di lavoro è implementato tramite Criteri di gruppo (configurazione computer) per garantire impostazioni coerenti su tutti i controller di dominio.

Implementazione di riferimento inclusa in questo repository (report GPO):

  • Nome archivio/report: T0-C-Analytics-DNSDebugLogging
  • ID backup: {2B6F16BC-0E7C-4787-83D7-2854FED882EE}
  • Target link GPO: corp.company.com/Domain Controllers
  • Filtro elementi (usato sia per il deployment dei file che per le attività pianificate): si applica solo se esiste C:\Windows\System32\dns.exe

1) Prerequisiti (cartelle + modulo)

Il backup fornito presuppone che queste cartelle esistano già. Aggiungi elementi GPP separati se vuoi che il deployment le crei automaticamente:

  • C:\Administration\Scripts
  • C:\Administration\Logs\DNSServer

Il backup fornito presuppone anche che Convert-DNSDebugLogFile sia già disponibile sui DC. L’attività di conversione avvia Windows PowerShell 5.1 con -NoProfile e non importa esplicitamente il modulo, quindi il modulo deve essere installato in un percorso modulo PowerShell a livello macchina visibile a LocalSystem. Approcci consigliati:

  • Installa DNSServer.DebugLogParser sui DC. Ad esempio, da PowerShell Gallery (se la policy lo consente).
  • Distribuisci il modulo tramite repository interno/condivisione file così che sia rilevabile in $env:PSModulePath
  • Aggiungi un esplicito Import-Module all’azione dell’attività se vuoi un comportamento di caricamento deterministico

2) Distribuire lo script di configurazione del debug logging (GPP Files)

La GPO distribuisce lo script:

  • Sorgente (in SYSVOL tramite GPP): %GptPath%\Preferences\Files\Set-DNSServerDebugLogging.ps1
  • Destinazione (su ogni DC): C:\Administration\Scripts\Set-DNSServerDebugLogging.ps1

Questo è implementato nell’elemento preferenze GPP Files in Files.xml.

3) Attività pianificata: configurare il debug logging DNS

La GPO crea un’attività pianificata chiamata Set-DNSServerDebugLogging.

  • Contesto di sicurezza nel backup fornito: SYSTEM con tipo di accesso S4U
  • Trigger nel backup fornito: giornaliero (inizio 2025-03-01T00:00:01)
  • Azione in ScheduledTasks.xml:
    • powershell.exe -ExecutionPolicy RemoteSigned -command " & { C:\Administration\Scripts\Set-DNSServerDebugLogging.ps1 }"
    • Directory di lavoro: C:\Administration\Scripts

Lo script Set-DNSServerDebugLogging.ps1 configura il debug logging DNS tramite Get-DnsServerDiagnostics / Set-DnsServerDiagnostics e (in particolare):

  • Abilita il logging su file + rollover
  • Scrive in: C:\Administration\Logs\DNSServer\DnsDebugLog_<COMPUTERNAME>.<Domain>_.log
  • Usa una dimensione di rollover di 10 MB per file
  • Cattura principalmente attività correlate alle query (query + notifiche + aggiornamenti + transazioni di domanda) ed esclude il logging completo dei pacchetti

4) Attività pianificata: convertire i log di debug ruotati in CSV compressi

La GPO crea un’attività pianificata chiamata Convert-DNSDebugLogs.

  • Contesto di sicurezza nel backup fornito: SYSTEM con tipo di accesso InteractiveToken
  • Trigger nel backup fornito: giornaliero (inizio 2026-01-01T00:30:00)
  • Directory di lavoro: C:\Administration\Logs\DNSServer
  • Azione in ScheduledTasks.xml (formattata per leggibilità):
Get-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

Note di progettazione:

  • Select-Object -Skip 1 evita intenzionalmente di processare il file di log più recente (attivo). Convert-DNSDebugLogFile è in grado di leggere un log che DNS Server ha attualmente aperto, ma quel file cambia mentre viene letto: l’output può mancare le voci più recenti o terminare con un record troncato, e due esecuzioni non producono risultati identici. Saltare il file attivo mantiene l’output pianificato riproducibile.
  • Ciò significa che i dati correnti vengono esportati solo dopo il rollover; su DC a basso volume, il log attivo può rimanere non processato per più di un giorno. Riduci la dimensione di rollover se questo ritardo è troppo lungo per il tuo caso d’uso.
  • Poiché Convert-DNSDebugLogFile imposta di default -OutputFile su “stessa cartella, stesso nome, .csv”, gli output finiscono accanto agli input *.log.
  • Con -CompressOutput, ogni log processato produce un *.zip e i CSV intermedi vengono rimossi.
  • A meno che non archivi o elimini i file *.log processati, le esecuzioni successive rielaboreranno ogni log non attivo.
  • L’attività genera un errore se $Error.Count -gt 0 per segnalare un’esecuzione fallita.

5) Ingestione centrale

Opzioni (scegli una):

  • Ingestione da condivisione file: il DC scrive (o copia) C:\Administration\Logs\DNSServer\*.zip in \\fileserver\share\dns\$env:COMPUTERNAME\... (concedi diritti di condivisione e NTFS agli account computer DC o al gruppo Domain Controllers se l’attività gira come SYSTEM)
  • Modello pull: lavoro centrale legge \\dc\C$\Administration\Logs\DNSServer\*.zip (meno preferito; richiede condivisioni amministrative)
  • Inoltro agente: SIEM / pipeline di log che spedisce gli output *.zip

Considerazioni operative

  • Privilegi minimi: le attività girano come SYSTEM; assicurati che le cartelle locali siano scrivibili e che eventuali destinazioni UNC concedano accesso all’account computer se usate.
  • Policy di firma: entrambe le attività usano -ExecutionPolicy RemoteSigned; firma o sblocca lo script e il modulo distribuiti secondo la tua policy.
  • Uso disco: -CompressOutput aiuta significativamente, ma questo flusso di lavoro non rimuove i log sorgente; pianifica conservazione e pulizia.
  • Comportamento di rielaborazione: a meno che non archivi o elimini i log processati, l’attività di conversione processerà ogni file *.log non attivo di nuovo nelle esecuzioni successive. È semplice e robusto, ma può sovrascrivere output e creare duplicati a valle se il tuo collector non fa deduplicazione.
  • Consolidamento multi-DC: -ComputerName $env:COMPUTERNAME è incluso così i dataset consolidati rimangono tracciabili. Nota che -ComputerName etichetta solo l’output — non esegue connessioni remote.
  • Condivisioni di rete: Convert-DNSDebugLogFile può leggere i log sorgente da percorsi SMB/UNC, ma convertire localmente e spedire i risultati compressi rimane il modello migliore per log grezzi grandi. Se usi un percorso UNC, ricorda che un’attività che gira come SYSTEM si autentica in rete come account computer e necessita di diritti di condivisione e NTFS lì.
  • Formato data: -OutputCulture sv-SE è usato deliberatamente così i timestamp sono scritti come 2026-01-20 23:00:16. Quel formato è letto senza ambiguità da SQL Server, Power BI e la maggior parte degli strumenti di importazione, indipendentemente dalla localizzazione del DC che ha prodotto il log.
  • Validazione: la validazione dell’intestazione rimane abilitata perché l’attività non usa -SkipHeaderValidation (consigliato).

Validare e adattare (usando lo ZIP)

Usa l’archivio ZIP come implementazione di riferimento, quindi allinea i seguenti aspetti al tuo ambiente:

  • Ambito target: quali DC / OU ricevono la policy
  • Identità di esecuzione: conferma che entrambe le attività pianificate usino il tipo di accesso previsto (S4U vs InteractiveToken) o normalizzali al tuo standard
  • Creazione cartelle: decidi se C:\Administration\Scripts e C:\Administration\Logs\DNSServer sono pre-creati altrove o devono essere creati da ulteriori elementi GPP
  • Percorsi: conferma che C:\Administration\Scripts e C:\Administration\Logs\DNSServer corrispondano ai tuoi standard
  • Conservazione: decidi se mantenere i log grezzi e per quanto tempo (specialmente se abiliti opzioni di pulizia)
  • Ingestione: conferma dove vengono scritti gli output CSV/ZIP e come vengono raccolti centralmente

Se vuoi validare la configurazione esatta della GPO senza importarla, le fonti autorevoli in questo repo sono: