【发布时间】:2021-10-01 12:55:06
【问题描述】:
我正在尝试使用 PowerShell 在 Windows Server DNS 中批量编辑 DNS TTL。
我真正无法理解的是我从Get-DnsServerResourceRecord 获得的记录对象中没有任何 FQDN。
我的 DNS 设置有一个主要区域和许多子域。
primaryzone.tld
├── sub1
│ ├── record1
│ ├── record2
│ └── subsub1
│ ├── (same as parent)
│ ├── record1.1
│ └── record2.1
├── sub2
└── sub3
由于不可能使用Get-DnsServerResourceRecord 进行递归,我必须遍历无法以编程方式收集的子域,以获取所有记录,而不仅仅是区域根级别的记录:
$DNSServer = "dc.company.tld"
$Zone = "primaryzone.tld"
$ChildZone = "sub1"
$SubDomains = @("","subsub1")
ForEach ($SubDomain in $SubDomains){
if ( $SubDomain -ne "" ) {
$FullDomain = "$($SubDomain).$($ChildZone)"
}
else {
$FullDomain = $ChildZone
}
Get-DnsServerResourceRecord -ComputerName $DNSServer -ZoneName $Zone -Name "$($FullDomain)"
真的应该这样吗?
如果我现在想更改 subsub1 下所有记录的 TTL,我可以这样尝试:
Get-DnsServerResourceRecord -ComputerName $DNSServer -ZoneName $Zone -Name "$($FullDomain)" |
ForEach-Object{
$newRecord = $_.Clone()
$newRecord.TimeToLive = $ttl
Set-DnsServerResourceRecord -ComputerName $DNSServer -NewInputObject $newRecord -OldInputObject $_ -ZoneName $Zone
}
这适用于subsub1 (same as parent) 记录,它具有subsub1.sub1 的HostName 属性,因此在primaryzone.tld 中提供了完整路径。而record1.1 有一个HostName 或record1.1 剥离它在树中位置的任何信息。这会导致此错误:
Set-DnsServerResourceRecord : Resource record in OldInputObject not found in primaryzone.tld zone on dc.company.tld server.
At C:\Users\me\Desktop\dns_ttl.ps1:24 char:13
+ Set-DnsServerResourceRecord -ComputerName $DNSServer -NewInputObject ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (dc.company.tld:root/Microsoft/...rResourceRecord) [Set-DnsServerResourceRecord], CimException
+ FullyQualifiedErrorId : WIN32 9714,Set-DnsServerResourceRecord
我将此解释为 Set-DnsServerResourceRecord 没有找到 OldInputObject 记录,因为它不知道在哪里查找,除了区域的根级别。
为什么我可以为Get-DnsServerResourceRecord 指定-Name subdomain,但是用Set-DnsServerResourceRecord 写回它时不需要-Name 参数?
为什么不记录不包含任何关于其在区域中的绝对 (FQDN) 位置信息的对象?
这么简单的事情怎么会这么难?
编辑:
我根据@Cpt.Whale 的建议更改了我的脚本
$DNSServer = "dc.company.tld"
$TargetZone = "primary.tld"
$TTL = [System.TimeSpan]::FromMinutes(1)
$SubDomain = "sub.primary.tld"
$Zones = Get-DnsServerZone -ComputerName $DNSServer | Where {
$_.ZoneType -eq 'Primary' -and
$_.IsReverseLookupZone -eq $false -and
$_.ZoneName -ne 'TrustAnchors' -and
$_.ZoneName -eq $TargetZone
}
Foreach ($DnsZone in $Zones) {
# Get all records in zone by not specifying -Name:
$Records = $DnsZone | Get-DnsServerResourceRecord -ComputerName $DNSServer
$Records | Foreach {
if ($_.HostName -match "$SubDomain$") {
if ($_.TimeToLive -ne $TTL) {
# This weird copy is due to awkward CIM references
$oldRecord = $_
$newRecord = $_.Clone()
$newRecord.TimeToLive = $TTL
# Update the TTL on the existing record:
Set-DnsServerResourceRecord -ComputerName $DNSServer -Old $oldRecord -New $newRecord -ZoneName $DnsZone.ZoneName
# Report changes
"{0,-50} TTL changed from {1,12} to {2,12}" -f $_.HostName, $_.TimeToLive, $TTL
}
}
}
}
有了这个我得到了完整的HostName,但仍然是我上面描述的错误
【问题讨论】:
标签: windows powershell dns