Я использую PowerShell для подключения и получения нескольких конфигураций DNS для выполнения некоторых проверок. Я подключаюсь к серверам и извлекаю необработанный файл конфигурации зоны в переменную. Для меня было бы проще преобразовать конфигурацию зоны в CSV, чтобы я мог запрашивать и сравнивать различные данные в моем скрипте. У меня есть регулярное выражение, которое вызывает одну строку, но я изо всех сил пытаюсь понять, как сделать несколько строк, связывая группы зон вместе. Вот соответствующая часть скрипта.
# What the output looks like when pulled from BIND:
$configurationText = @"
// DNS Zone configuration file
// Root server list
zone "." IN {
type hint;
file "root.hints";
};
zone "my.domain.com" IN {
type primary;
file "zones/zone.my.domain.com";
};
zone "my.domain.org" IN {
type primary;
file "zones/zone.my.domain.org";
};
"@
# Multiline Regex query
$regex = @"
(?<=zone ")(?<zone>.*?)(? = ")
(?<=type )(?<type>.*?)(?=;)
(?<=file ")(?<file>.*?)(? = ")
"@
# Test if this matches !
select-string -InputObject $configurationText -pattern $regex -allmatch | ForEach-Object { $_.Matches } | Out-GridView
Я также попытался выполнить поиск и замену, чтобы поместить его в формат csv, но не могу понять, как удалить новую строку после ';'
$DNSTemp = $configurationText -replace '// DNS Zone configuration file','Zone,Type,File'
$DNSTemp = $DNSTemp -replace '// Root server list',""
$DNSTemp = $DNSTemp -replace '.*zone "',''
$DNSTemp = $DNSTemp -replace '.*type ',''
$DNSTemp = $DNSTemp -replace '.*file "',''
$DNSTemp = $DNSTemp -replace '" IN {',';'
$DNSTemp = $DNSTemp -replace '};',''
$DNSTemp = $DNSTemp -replace '";',';'
# This is the replacement that doesn't work.
$DNSTemp = $DNSTemp -replace ';`n',','
Это также не сработает, если кто-то по-королевски испортит файлы зон.





Это не полное решение, но, надеюсь, оно поможет вам решить вашу проблему.
Вы можете использовать полный класс регулярных выражений в .Net, чтобы получить больше возможностей. Таким образом, этот фрагмент вернет все соответствующие зоны.
$regex = [regex]::new('zone \W(?<zone>[.\w]+)\W IN {\s+type (?<type>\w+);\s+file \W(?<file>\S+)\W;', [System.Text.RegularExpressions.RegexOptions]::Multiline -band [System.Text.RegularExpressions.RegexOptions]::IgnoreCase )
$matches = $regex.Matches($configurationText)
Затем вы можете просмотреть именованные группы в $matches.
foreach ($zone in $matches.Groups) { $zone.Captures | Where-Object Name -eq zone | Select-Object -ExpandProperty Value }
Спасибо @логическаядиаграмма, которая сработала для меня. Мне удалось сгруппировать значения, добавив к вашему предложению следующее:
$regex = [regex]::new('zone \W(?<domain>[.\w]+)\W IN {\s+type (?<type>\w+);\s+file \W(?<file>\S+)\W;', [System.Text.RegularExpressions.RegexOptions]::Multiline -band [System.Text.RegularExpressions.RegexOptions]::IgnoreCase )
$matches = $regex.Matches($configurationText)
$DNS1Zones = foreach ($Match in $matches) {
$Domain = $Match.Groups | Where-Object Name -eq domain | Select-Object -ExpandProperty Value
$Type = $Match.Groups | Where-Object Name -eq type | Select-Object -ExpandProperty Value
$File = $Match.Groups | Where-Object Name -eq File | Select-Object -ExpandProperty Value
[PSCustomObject]@{
PSTypeName = "Zone"
Domain = $Domain
Type = $Type
File = $File
}
}
$DNS1Zones | Out-GridView
$DNS1Zones | Where-Object type -eq primary
$Zone1 = $DNS1Zones | Where-Object domain -eq my.domain.com