functions/servers/Test-FMServer.ps1

function Test-FMServer
{
    <#
        .SYNOPSIS
            Checks whether the Domain Controller in a forest are in the correct site.
         
        .DESCRIPTION
            Checks whether the Domain Controller in a forest are in the correct site.
         
        .PARAMETER Server
            The server / domain to work with.
         
        .PARAMETER Credential
            The credentials to use for this operation.
         
        .EXAMPLE
            PS C:\> Test-FMServer
 
            Tests, whethether all domain controllers in the current forest are up-to-date.
    #>

    [CmdletBinding()]
    Param (
        [PSFComputer]
        $Server,

        [PSCredential]
        $Credential
    )
    
    begin
    {
        $parameters = $PSBoundParameters | ConvertTo-PSFHashtable -Include Server, Credential
        $parameters['Debug'] = $false
        Assert-ADConnection @parameters -Cmdlet $PSCmdlet
        $rootDSE = Get-ADRootDSE @parameters
        $searchBase = "CN=Sites,$($rootDSE.configurationNamingContext)"
        $domainControllers = Get-ADObject @parameters -LDAPFilter '(objectClass=server)' -SearchBase $searchBase -Properties * | Select-Object *, IPAddress, @{
            Name = 'SiteName'
            Expression = { $_.DistinguishedName -replace ".+,CN=(.+?),CN=Sites,CN=Configuration,DC=.+",'$1' }
        }
        foreach ($domainController in $domainControllers) {
            if ($domainController.DNSHostName) {
                $domainController.IPAddress = [IPAddress](Resolve-DnsName -Name $domainController.DNSHostName -ErrorAction Ignore -Debug:$false | Where-Object Type -eq A | Select-Object -First 1).IPAddress
            }
        }
        $allSubnets = Get-ADReplicationSubnet @parameters -Filter * -Properties Description | Select-PSFObject 'Name',  @{
            Name = "SiteName"
            Expression = { ($_.Site | Get-ADObject @parameters).Name }
        }, 'Name.Split("/")[0] AS IPBase TO IPAddress', 'Name.Split("/")[1].Split("´n")[0] AS MaskSize To Int', Mask, site | Where-Object Name -notlike "*CNF*" | Sort-Object MaskSize -Descending
        foreach ($subnet in $allSubnets) {
            $subnet.Mask = ConvertTo-SubnetMask -MaskSize $subnet.MaskSize
        }
    }
    process
    {
        :main foreach ($domainController in $domainControllers) {
            #region No IP Address
            if (-not $domainController.IPAddress) {
                [PSCustomObject]@{
                    PSTypeName = 'ForestManagement.Server.TestResult'
                    Type = 'AddressNotFound'
                    ObjectType = 'Server'
                    Identity = $domainController.Name
                    Changed = $null
                    Server = $Server
                    CurrentSite = $domainController.SiteName
                    SupposedSite = $null
                    FoundSubnet = $null
                    ADObject = $domainController
                }
                continue
            }
            #endregion No IP Address

            #region Resolving Subnet
            $foundSubnet = $null
            foreach ($subnet in $allSubnets) {
                if (Test-Subnet -NetworkAddress $subnet.IPBase -MaskAddress $subnet.Mask -HostAddress $domainController.IPAddress) {
                    $foundSubnet = $subnet
                    break
                }
            }

            if (-not $foundSubnet) {
                [PSCustomObject]@{
                    PSTypeName = 'ForestManagement.Server.TestResult'
                    Type = 'NoMatchingSubnet'
                    ObjectType = 'Server'
                    Identity = $domainController.Name
                    Changed = $null
                    Server = $Server
                    CurrentSite = $domainController.SiteName
                    SupposedSite = $null
                    FoundSubnet = $null
                    ADObject = $domainController
                }
                continue
            }
            #endregion Resolving Subnet

            if ($domainController.SiteName -ne $foundSubnet.SiteName) {
                $currentSiteSubnets = $allSubnets | Where-Object SiteName -eq $domainController.SiteName
                foreach ($subnet in $currentSiteSubnets) {
                    # Domain Controller is legally in his current site
                    if (Test-Subnet -NetworkAddress $subnet.IPBase -MaskAddress $subnet.Mask -HostAddress $domainController.IPAddress) {
                        Write-PSFMessage -Level InternalComment -String 'Test-FMServer.SiteConflict' -StringValues $domainController.Name, $foundSubnet.SiteName, $domainController.SiteName, $foundSubnet.Name -Tag 'note' -Target $domainController.Name
                        continue main
                    }
                }

                [PSCustomObject]@{
                    PSTypeName = 'ForestManagement.Server.TestResult'
                    Type = 'BadSite'
                    ObjectType = 'Server'
                    Identity = $domainController.Name
                    Changed = $foundSubnet.SiteName
                    Server = $Server
                    CurrentSite = $domainController.SiteName
                    SupposedSite = $foundSubnet.SiteName
                    FoundSubnet = $foundSubnet
                    ADObject = $domainController
                }
            }
        }
    }
}