Providers/AD/Private/Get-ADTestDnsZoneObject.ps1

function Get-ADTestDnsZoneObject {
    <#
    .SYNOPSIS
        Finds the directory object behind a DNS zone, wherever the partition it lives in

    .DESCRIPTION
        An Active Directory-integrated zone is a directory object, which is what lets this
        provider stamp it with the seed tag and prove later that it created it. Finding that
        object is not as simple as asking for it, because it does not live in the domain
        naming context: a zone replicated to the domain sits under
        `DC=DomainDnsZones,<domain>`, one replicated to the forest under
        `DC=ForestDnsZones,<forest>`, and a legacy one under `CN=MicrosoftDNS,CN=System`.

        A `Get-ADObject` with no search base only looks in the domain naming context, so it
        finds none of the first two and silently returns nothing. That is not a loud failure:
        the zone gets created, the tag never gets written, and teardown then refuses to
        remove a zone this module made because it cannot prove it. That happened, which is
        why the search base is explicit here and why all three partitions are tried.

    .PARAMETER ZoneName
        The DNS zone name, as the DNS server reports it.

    .PARAMETER DomainDN
        The domain's distinguished name. Defaults to the connected domain's.

    .OUTPUTS
        The directory object, or nothing when the zone is not directory-integrated.

    .EXAMPLE
        PS> Get-ADTestDnsZoneObject -ZoneName 'zz-test-lab.ad.contoso.com'

        DESCRIPTION: Finds the object so it can be tagged or checked
        OUTPUT: An ADObject with its adminDescription
        USE CASE: Called when the zone is created, and again at teardown to prove ownership

    .NOTES
        Author: Jeffrey Stuhr
        Blog: https://www.techbyjeff.net
        LinkedIn: https://www.linkedin.com/in/jeffrey-stuhr-034214aa/
    #>


    [CmdletBinding()]
    [OutputType([object])]
    param(
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]$ZoneName,

        [Parameter()]
        [string]$DomainDN
    )

    if (-not $DomainDN) { $DomainDN = (Get-ADTestDomain).DomainDN }

    # The forest partition's name is the forest root, which is the domain's own name unless
    # this is a child domain; deriving it from the domain DN is close enough to try.
    $searchBases = @(
        "DC=DomainDnsZones,$DomainDN"
        "DC=ForestDnsZones,$DomainDN"
        "CN=MicrosoftDNS,CN=System,$DomainDN"
    )

    foreach ($searchBase in $searchBases) {
        try {
            $found = Get-ADObject -LDAPFilter "(&(objectClass=dnsZone)(name=$ZoneName))" `
                -SearchBase $searchBase -Properties adminDescription -ErrorAction Stop |
                Select-Object -First 1
            if ($found) {
                Write-Verbose "Zone '$ZoneName' found under $searchBase"
                return $found
            }
        }
        catch {
            Write-Verbose "Partition $searchBase did not answer: $($_.Exception.Message)"
        }
    }

    Write-Verbose "No directory object found for zone '$ZoneName'"
    return $null
}