309 lines
13 KiB
PowerShell
309 lines
13 KiB
PowerShell
# exportDns.ps1 - Export DNS zones and records from Windows AD DNS
|
|
# Script d'exportation complète DNS pour migration vers Samba4
|
|
|
|
Write-Host "=== Début de l'exportation DNS Windows AD ===" -ForegroundColor Green
|
|
|
|
# Vérifier que le module DnsServer est disponible
|
|
try {
|
|
Import-Module DnsServer -ErrorAction Stop
|
|
Write-Host "[OK] Module DnsServer chargé avec succès"
|
|
} catch {
|
|
Write-Host "[ERREUR] Module DnsServer non disponible. Installer RSAT DNS ou exécuter sur un serveur DNS" -ForegroundColor Red
|
|
exit 1
|
|
}
|
|
|
|
# Créer le répertoire d'export
|
|
$ExportPath = "C:\temp\dns-export"
|
|
if (!(Test-Path $ExportPath)) {
|
|
New-Item -ItemType Directory -Path $ExportPath -Force | Out-Null
|
|
Write-Host " Répertoire d'export créé: $ExportPath"
|
|
}
|
|
|
|
# Initialiser les variables d'export
|
|
$DnsExport = @{
|
|
'ExportDate' = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
|
'ExportedBy' = $env:USERNAME
|
|
'ServerName' = $env:COMPUTERNAME
|
|
'Zones' = @()
|
|
'Statistics' = @{
|
|
'TotalZones' = 0
|
|
'ForwardZones' = 0
|
|
'ReverseZones' = 0
|
|
'TotalRecords' = 0
|
|
}
|
|
}
|
|
|
|
# ===== EXPORT DES ZONES DNS =====
|
|
Write-Host "`n1. Récupération de toutes les zones DNS..." -ForegroundColor Yellow
|
|
|
|
try {
|
|
$AllZones = Get-DnsServerZone
|
|
$DnsExport.Statistics.TotalZones = $AllZones.Count
|
|
Write-Host "[OK] $($AllZones.Count) zones trouvées"
|
|
|
|
foreach ($Zone in $AllZones) {
|
|
Write-Host " Traitement de la zone: $($Zone.ZoneName)" -ForegroundColor Cyan
|
|
|
|
# Déterminer le type de zone
|
|
$ZoneType = "Unknown"
|
|
$IsReverse = $false
|
|
|
|
if ($Zone.ZoneName -like "*.in-addr.arpa" -or $Zone.ZoneName -like "*.ip6.arpa") {
|
|
$ZoneType = "Reverse"
|
|
$IsReverse = $true
|
|
$DnsExport.Statistics.ReverseZones++
|
|
} elseif ($Zone.ZoneName -eq "." -or $Zone.ZoneName -eq "..") {
|
|
$ZoneType = "Root"
|
|
} elseif ($Zone.ZoneName -like "_*") {
|
|
$ZoneType = "Service"
|
|
} else {
|
|
$ZoneType = "Forward"
|
|
$DnsExport.Statistics.ForwardZones++
|
|
}
|
|
|
|
# Créer l'objet zone
|
|
$ZoneData = [PSCustomObject]@{
|
|
'ZoneName' = $Zone.ZoneName
|
|
'ZoneType' = $ZoneType
|
|
'IsReverse' = $IsReverse
|
|
'IsPrimary' = $Zone.ZoneType -eq "Primary"
|
|
'IsStub' = $Zone.ZoneType -eq "Stub"
|
|
'IsForwarder' = $Zone.ZoneType -eq "Forwarder"
|
|
'DynamicUpdate' = $Zone.DynamicUpdate.ToString()
|
|
'Records' = @()
|
|
}
|
|
|
|
# ===== EXPORT DES ENREGISTREMENTS =====
|
|
try {
|
|
$Records = Get-DnsServerResourceRecord -ZoneName $Zone.ZoneName -ErrorAction Stop
|
|
Write-Host " -> $($Records.Count) enregistrements trouvés"
|
|
|
|
foreach ($Record in $Records) {
|
|
$RecordData = $null
|
|
$RecordValue = ""
|
|
|
|
# Extraire les données selon le type d'enregistrement
|
|
switch ($Record.RecordType) {
|
|
"A" {
|
|
$RecordValue = $Record.RecordData.IPv4Address.ToString()
|
|
}
|
|
"AAAA" {
|
|
$RecordValue = $Record.RecordData.IPv6Address.ToString()
|
|
}
|
|
"CNAME" {
|
|
$RecordValue = $Record.RecordData.HostNameAlias.ToString()
|
|
}
|
|
"MX" {
|
|
$RecordValue = "$($Record.RecordData.Preference):$($Record.RecordData.MailExchange)"
|
|
}
|
|
"NS" {
|
|
$RecordValue = $Record.RecordData.NameServer.ToString()
|
|
}
|
|
"PTR" {
|
|
$RecordValue = $Record.RecordData.PtrDomainName.ToString()
|
|
}
|
|
"SRV" {
|
|
$RecordValue = "$($Record.RecordData.Priority):$($Record.RecordData.Weight):$($Record.RecordData.Port):$($Record.RecordData.DomainName)"
|
|
}
|
|
"TXT" {
|
|
$RecordValue = $Record.RecordData.DescriptiveText -join " "
|
|
}
|
|
"SOA" {
|
|
$RecordValue = "$($Record.RecordData.PrimaryServer):$($Record.RecordData.ResponsiblePerson):$($Record.RecordData.SerialNumber)"
|
|
}
|
|
default {
|
|
$RecordValue = $Record.RecordData.ToString()
|
|
}
|
|
}
|
|
|
|
# Créer l'objet enregistrement
|
|
$RecordObj = [PSCustomObject]@{
|
|
'Name' = if ($Record.HostName -eq "@") { "@" } else { $Record.HostName }
|
|
'Type' = $Record.RecordType.ToString()
|
|
'TTL' = $Record.TimeToLive.TotalSeconds
|
|
'Value' = $RecordValue
|
|
'Timestamp' = if ($Record.Timestamp) { $Record.Timestamp.ToString("yyyy-MM-dd HH:mm:ss") } else { "Static" }
|
|
}
|
|
|
|
$ZoneData.Records += $RecordObj
|
|
$DnsExport.Statistics.TotalRecords++
|
|
}
|
|
|
|
} catch {
|
|
Write-Host " Erreur lors de la lecture des enregistrements: $($_.Exception.Message)" -ForegroundColor Yellow
|
|
}
|
|
|
|
$DnsExport.Zones += $ZoneData
|
|
}
|
|
|
|
} catch {
|
|
Write-Host " Erreur lors de la récupération des zones: $($_.Exception.Message)" -ForegroundColor Red
|
|
exit 1
|
|
}
|
|
|
|
# ===== EXPORT VERS FICHIERS =====
|
|
Write-Host "`n2. Export vers fichiers..." -ForegroundColor Yellow
|
|
|
|
# Export JSON complet
|
|
$JsonFile = "$ExportPath\dns_export_complete.json"
|
|
$DnsExport | ConvertTo-Json -Depth 10 | Out-File -FilePath $JsonFile -Encoding UTF8
|
|
Write-Host "[OK] Export JSON: $JsonFile"
|
|
|
|
# Export CSV des zones
|
|
$CsvZonesFile = "$ExportPath\dns_zones.csv"
|
|
$DnsExport.Zones | Select-Object ZoneName, ZoneType, IsReverse, IsPrimary, DynamicUpdate, @{Name='RecordCount';Expression={$_.Records.Count}} |
|
|
Export-Csv -Path $CsvZonesFile -NoTypeInformation -Encoding UTF8
|
|
Write-Host "[OK] Export CSV zones: $CsvZonesFile"
|
|
|
|
# Export CSV des enregistrements par zone
|
|
foreach ($Zone in $DnsExport.Zones) {
|
|
if ($Zone.Records.Count -gt 0) {
|
|
$SafeZoneName = $Zone.ZoneName -replace '[<>:"/\\|?*]', '_'
|
|
$CsvRecordsFile = "$ExportPath\dns_records_$SafeZoneName.csv"
|
|
$Zone.Records | Export-Csv -Path $CsvRecordsFile -NoTypeInformation -Encoding UTF8
|
|
Write-Host " -> Enregistrements zone $($Zone.ZoneName): $CsvRecordsFile"
|
|
}
|
|
}
|
|
|
|
# Export BIND format pour zones principales
|
|
Write-Host "`n3. Export format BIND..." -ForegroundColor Yellow
|
|
$BindExportPath = "$ExportPath\bind-zones"
|
|
if (!(Test-Path $BindExportPath)) {
|
|
New-Item -ItemType Directory -Path $BindExportPath -Force | Out-Null
|
|
}
|
|
|
|
foreach ($Zone in ($DnsExport.Zones | Where-Object {$_.ZoneType -eq "Forward" -and $_.IsPrimary})) {
|
|
$SafeZoneName = $Zone.ZoneName -replace '[<>:"/\\|?*]', '_'
|
|
$BindFile = "$BindExportPath\db.$SafeZoneName"
|
|
|
|
# Créer le fichier de zone BIND
|
|
$BindContent = @()
|
|
$BindContent += "; Zone file for $($Zone.ZoneName)"
|
|
$BindContent += "; Exported from Windows DNS on $(Get-Date)"
|
|
$BindContent += "; TTL default: 3600"
|
|
$BindContent += '$TTL 3600'
|
|
$BindContent += ""
|
|
|
|
# Ajouter les enregistrements
|
|
foreach ($Record in $Zone.Records) {
|
|
$Name = if ($Record.Name -eq "@") { "@" } else { $Record.Name }
|
|
$TTL = if ($Record.TTL -gt 0) { $Record.TTL } else { "3600" }
|
|
|
|
switch ($Record.Type) {
|
|
"A" { $BindContent += "$Name`t$TTL`tIN`tA`t$($Record.Value)" }
|
|
"AAAA" { $BindContent += "$Name`t$TTL`tIN`tAAAA`t$($Record.Value)" }
|
|
"CNAME" { $BindContent += "$Name`t$TTL`tIN`tCNAME`t$($Record.Value)" }
|
|
"MX" {
|
|
$MxParts = $Record.Value -split ":"
|
|
$BindContent += "$Name`t$TTL`tIN`tMX`t$($MxParts[0])`t$($MxParts[1])"
|
|
}
|
|
"NS" { $BindContent += "$Name`t$TTL`tIN`tNS`t$($Record.Value)" }
|
|
"TXT" { $BindContent += "$Name`t$TTL`tIN`tTXT`t`"$($Record.Value)`"" }
|
|
"SRV" {
|
|
$SrvParts = $Record.Value -split ":"
|
|
if ($SrvParts.Count -eq 4) {
|
|
$BindContent += "$Name`t$TTL`tIN`tSRV`t$($SrvParts[0])`t$($SrvParts[1])`t$($SrvParts[2])`t$($SrvParts[3])"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
$BindContent | Out-File -FilePath $BindFile -Encoding UTF8
|
|
Write-Host " -> Zone BIND $($Zone.ZoneName): $BindFile"
|
|
}
|
|
|
|
# ===== SCRIPT D'IMPORT POUR SAMBA =====
|
|
Write-Host "`n4. Génération du script d'import Samba..." -ForegroundColor Yellow
|
|
$ImportScript = "$ExportPath\import_dns_samba.sh"
|
|
$ImportContent = @()
|
|
$ImportContent += "#!/bin/bash"
|
|
$ImportContent += "# Script d'import DNS pour Samba4"
|
|
$ImportContent += "# Généré automatiquement depuis exportDns.ps1"
|
|
$ImportContent += "# Date: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
|
|
$ImportContent += ""
|
|
$ImportContent += "# Vérifier que samba-tool est disponible"
|
|
$ImportContent += "if ! command -v samba-tool &> /dev/null; then"
|
|
$ImportContent += " echo 'Erreur: samba-tool non trouvé'"
|
|
$ImportContent += " exit 1"
|
|
$ImportContent += "fi"
|
|
$ImportContent += ""
|
|
$ImportContent += "# Demander les credentials une seule fois"
|
|
$ImportContent += "echo '=== Import des zones et enregistrements DNS vers Samba4 ==='"
|
|
$ImportContent += "echo"
|
|
$ImportContent += "read -p 'Nom d'\''utilisateur administrateur Samba [Administrator]: ' SAMBA_USER"
|
|
$ImportContent += "SAMBA_USER=`${SAMBA_USER:-Administrator}"
|
|
$ImportContent += ""
|
|
$ImportContent += "echo -n 'Mot de passe pour `$SAMBA_USER: '"
|
|
$ImportContent += "read -s SAMBA_PASSWORD"
|
|
$ImportContent += "echo"
|
|
$ImportContent += ""
|
|
$ImportContent += "# Vérifier les credentials avant de continuer"
|
|
$ImportContent += "echo 'Test des credentials...'"
|
|
$ImportContent += "if ! samba-tool user show '`$SAMBA_USER' --username='`$SAMBA_USER' --password='`$SAMBA_PASSWORD' &>/dev/null; then"
|
|
$ImportContent += " echo 'Erreur: Credentials invalides ou utilisateur non autorisé'"
|
|
$ImportContent += " exit 1"
|
|
$ImportContent += "fi"
|
|
$ImportContent += "echo '[OK] Credentials validés pour `$SAMBA_USER'"
|
|
$ImportContent += "echo"
|
|
$ImportContent += ""
|
|
$ImportContent += "# Mode dry-run optionnel"
|
|
$ImportContent += "read -p 'Mode dry-run (afficher les commandes sans les exécuter) ? [y/N]: ' DRY_RUN"
|
|
$ImportContent += "DRY_RUN=`${DRY_RUN:-N}"
|
|
$ImportContent += ""
|
|
$ImportContent += "if [[ '`$DRY_RUN' =~ ^[Yy]`$ ]]; then"
|
|
$ImportContent += " echo '[INFO] Mode dry-run activé - aucune modification ne sera effectuée'"
|
|
$ImportContent += " echo"
|
|
$ImportContent += "fi"
|
|
$ImportContent += ""
|
|
$ImportContent += "# Fonction pour exécuter les commandes samba-tool"
|
|
$ImportContent += "execute_samba_cmd() {"
|
|
$ImportContent += " local cmd='`$1'"
|
|
$ImportContent += " if [[ '`$DRY_RUN' =~ ^[Yy]`$ ]]; then"
|
|
$ImportContent += " echo '[DRY-RUN] `$cmd'"
|
|
$ImportContent += " else"
|
|
$ImportContent += " if eval '`$cmd'; then"
|
|
$ImportContent += " echo ' [OK] `$(echo '`$cmd' | cut -d'\'' '\'' -f5-6)'"
|
|
$ImportContent += " else"
|
|
$ImportContent += " echo ' [ERREUR] `$(echo '`$cmd' | cut -d'\'' '\'' -f5-6)'"
|
|
$ImportContent += " fi"
|
|
$ImportContent += " fi"
|
|
$ImportContent += "}"
|
|
$ImportContent += ""
|
|
$ImportContent += "echo 'Import des zones et enregistrements DNS vers Samba4...'"
|
|
$ImportContent += "echo"
|
|
|
|
# Générer les commandes pour chaque zone et enregistrement
|
|
foreach ($Zone in ($DnsExport.Zones | Where-Object {$_.ZoneType -eq "Forward" -and $_.IsPrimary -and $_.ZoneName -ne "." -and $_.ZoneName -ne ".." -and $_.ZoneName -notlike "_*"})) {
|
|
$ImportContent += "# Zone: $($Zone.ZoneName)"
|
|
$ImportContent += "echo 'Traitement de la zone: $($Zone.ZoneName)'"
|
|
$ImportContent += "create_zone_if_not_exists `"$($Zone.ZoneName)`""
|
|
|
|
foreach ($Record in $Zone.Records) {
|
|
if ($Record.Type -eq "A" -and $Record.Name -ne "@" -and $Record.Name -notlike "*._*") {
|
|
$ImportContent += "execute_samba_cmd 'samba-tool dns add localhost $($Zone.ZoneName) $($Record.Name) A $($Record.Value) --username=`"`$SAMBA_USER`" --password=`"`$SAMBA_PASSWORD`"'"
|
|
}
|
|
elseif ($Record.Type -eq "CNAME" -and $Record.Name -notlike "*._*") {
|
|
$ImportContent += "execute_samba_cmd 'samba-tool dns add localhost $($Zone.ZoneName) $($Record.Name) CNAME $($Record.Value) --username=`"`$SAMBA_USER`" --password=`"`$SAMBA_PASSWORD`"'"
|
|
}
|
|
}
|
|
$ImportContent += ""
|
|
}
|
|
|
|
$ImportContent | Out-File -FilePath $ImportScript -Encoding UTF8
|
|
Write-Host "[OK] Script d'import Samba: $ImportScript"
|
|
|
|
# ===== RÉSUMÉ =====
|
|
Write-Host "`n=== RÉSUMÉ DE L'EXPORT DNS ===" -ForegroundColor Green
|
|
Write-Host "Zones totales exportées : $($DnsExport.Statistics.TotalZones)"
|
|
Write-Host "Zones directes : $($DnsExport.Statistics.ForwardZones)"
|
|
Write-Host "Zones inverses : $($DnsExport.Statistics.ReverseZones)"
|
|
Write-Host "Enregistrements totaux : $($DnsExport.Statistics.TotalRecords)"
|
|
Write-Host ""
|
|
Write-Host "Fichiers générés :"
|
|
Write-Host "- Export complet JSON : dns_export_complete.json"
|
|
Write-Host "- Zones CSV : dns_zones.csv"
|
|
Write-Host "- Enregistrements CSV : dns_records_*.csv"
|
|
Write-Host "- Zones BIND : bind-zones/db.*"
|
|
Write-Host "- Script import Samba : import_dns_samba.sh"
|
|
Write-Host ""
|
|
Write-Host "[OK] Export DNS terminé avec succès dans : $ExportPath" -ForegroundColor Green |