【问题标题】:Change TTL for subdomain records in Windows Server DNS with PowerShell使用 PowerShell 更改 Windows Server DNS 中子域记录的 TTL
【发布时间】: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.sub1HostName 属性,因此在primaryzone.tld 中提供了完整路径。而record1.1 有一个HostNamerecord1.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


    【解决方案1】:

    DNS 记录类型的 cim 对象没有 ZoneName 属性,但它确实保留了子域 - 它是记录的 HostName 的一部分。 DNS 几乎不关心子域,除非它们是一个单独的区域。

    首先要仔细检查您是否实际上只有一个区域:

    $zones = Get-DnsServerZone -ComputerName $DNSServer | Where {
        $_.ZoneType -eq 'Primary' -and 
        $_.IsReverseLookupZone -eq $false -and
        $_.ZoneName -ne 'TrustAnchors'
    }
    $zones
    

    那么,例如:

    $TTL = [System.TimeSpan]::FromHours(2)  ## example TTL
    
    Foreach ($DnsZone in $Zones) {
      # Get all records in zone by not specifying -Name:
      $records = $DnsZone | Get-DnsServerResourceRecord -ComputerName $DNSServer
      $records | Foreach { 
        # This weird copy is due to awkward CIM references
        $old = $_
        $new = $_.Clone()
          $new.TimeToLive = $TTL
        # Update the TTL on the existing record:
        Set-DnsServerResourceRecord -ComputerName $DNSServer -Old $old -New $new -ZoneName $DnsZone.ZoneName
      }
    }
    

    【讨论】:

    • 我有多个区域,但只想更改一个区域的特定子域的 TTL,而不是所有区域中的所有记录。这就是为什么我想将-Name 传递给Get-DnsServerResourceRecord。此外,正如我在原始帖子中解释的那样,记录本身不会将子域保留为 HostName 的一部分。这是最让我困惑的。将整个区域导出为bind 格式时,主机名会附加相应的子域,正如我所料。但在使用Get-DnsServerResourceRecord 时不会。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-19
    • 1970-01-01
    • 2014-10-04
    • 2015-04-05
    • 1970-01-01
    • 2015-08-02
    • 2021-04-30
    相关资源
    最近更新 更多