>目标:我们需要更改 1,055 个区域的 PTR 记录。 我们需要更改每条记录的主机名。 超过10,000个条目...
我们目前被迫与 DNSCMD 合作,因为我们仍然是 2008 R2 域。
为了使此讨论简单,我将仅使用包含 1 台服务器的区域。
以此示例服务器为例:IP为 10.128.10.5 的 Thor.domain.com。如果使用以下命令导出此区域:
dnscmd /enumzones > AllZones.txt
for /f %a in (AllZones.txt) do dnscmd /ZoneExport %a export%a.txt`
它生成的文本文件包含如下内容:
; 10.128.10.in-addr.arpa 区域的数据库文件 (null)。 ; 区域版本:21 @ 在 SOA DomainControler.testdomain.com 中。hostmaster.testdomain.com。( 21 ;序号 900 ;刷新 600 ;重试 86400 ;到期 3600 ) ;默认 TTL ; 区域 NS 记录 @ NS DomainControler.testdomain.com。 ; 区域记录 5 PTR Thor.domain.com。
步骤 1 完成。当然,该脚本确实创建了 1,055 个不同的文本文件,每个 PTR 区域一个。 我们将只为本次讨论做一个。
我已经想出了如何清理此文件以使其几乎达到可以使用它来将其导入回DNS的阶段。为了准备此文件以重新导入,我已经对文本进行了一些按摩。
这是我到目前为止的脚本。
$ZoneName = Get-ChildItem -File C:PSDNSPTRexport | % {$_.BaseName}
$FileNames = Get-ChildItem -File C:PSDNSPTRexport | % {$_.Name}
foreach ($filename in $filenames) {
(Get-Content c:PSDNSPTRexport$filename) -replace "PTR","" -replace " ","" |
Select-Object -Skip 24 |
Out-File C:PSDNSPTROutput$fileName
}
这是做什么的:
- 删除对 PTR 的任何引用
- 删除所有空格
- 删除前 24 行文本
结果文件如下所示:
5 Thor.domain.com。
此外,此文件以区域命名:10.128.10.in-addr.arpa.txt
。
该文件现在需要将区域信息添加到每行文本中。这就是我被困住的地方。
我遇到困难的最后一步是获取文件名(区域信息)并将此文本放在文件中每行的开头,包括一个选项卡。
我指定了一个变量$ZoneName
它采用所有区域文件的文件名,但只获取 baseName(无扩展名)。
理论上,我想使用此变量创建一个如下所示的文件:
10.128.10.in-addr.arpa 5 Thor.domain.com
据我所知,我们将不得不删除所有 PTR 区域并重新添加它们。这可以在 GUI 中完成,但工作量很大。
一旦我按照上述格式格式化了这些文件,我应该能够使用这样的命令来导入它们。
for /f "tokens=1-4 delims=;" %%a in (PTRs2Add.txt) do (
dnscmd domaincontroller /RecordAdd %%a %%b %%c %%d >>addPTR.log
)
此特定命令要求我将所有结果文件合并为一个大文件。 我相信我可以找到一种更好的方法来解析我按摩的每个区域文件。
当然,如果我掉进了一个非常错误的兔子洞,我愿意接受其他建议,了解如何更改位于 1,055 个不同区域的 10,000 条 PTR 记录的主机名条目。
混合批处理和PowerShell以及导出/导入文件应该是必需的AFAICS。将dnscmd
输出写入输出流(vulgo STDOUT),并使用正则表达式提取相关信息:
& dnscmd /EnumZones | Where-Object {
$_ -match '^ (S+.in-addr.arpa)'
} | ForEach-Object {
$zone = $matches[1]
& dnscmd /ZonePrint $zone | Where-Object {
$_ -match '(S+)s+(?:d+)s+(?:PTR)s+(S+)'
} | ForEach-Object {
$data = $matches[1]
$name = $matches[2]
$newname = $name.Replace('.example.org.', '.example.com.')
& dnscmd /RecordDelete $zone $name PTR $data /f
& dnscmd /RecordAdd $zone $newname PTR $data /f
}
}
正如您已经怀疑的那样,修改记录包括删除和重新创建它。
如果您需要对应处理哪些区域进行更多控制,则可能需要从区域信息构建对象,并在该对象和枚举区域记录之间放置另一个Where-Object
筛选器:
& dnscmd /EnumZones | Where-Object {
$_ -match '^ (S+.in-addr.arpa)s+(S+)s+(S+)s+(S*)'
} | ForEach-Object {
New-Object -Type PSObject -Property ([ordered]@{
Name = $matches[1]
Type = $matches[2]
Storage = $matches[3]
Properties = $matches[4]
})
} | Where-Object {
# filter zones (optional), e.g.:
$_.Type -eq 'primary'
} | ForEach-Object {
$zone = $_.Name
& dnscmd /ZonePrint $zone | Where-Object {
$_ -match '(S+)s+(?:d+)s+(?:PTR)s+(S+)'
} | ForEach-Object {
$data = $matches[1]
$name = $matches[2]
$newname = $name.Replace('.example.org.', '.example.com.')
& dnscmd /RecordDelete $zone $name PTR $data /f
& dnscmd /RecordAdd $zone $newname PTR $data /f
}
}