Search code examples
powershelldnsactive-directorypowershell-5.1

Checking for DNS resolution errors


Problem: I currently have a script that will add a user to a device's admin group, and I have to use the hostname instead of the IP address. Occasionally using a hostname does not connect to the correct device (assuming) due to DNS being slow/having issues.

Question: Is there a way to resolve a hostname using AD and DNS then comparing if they are the same to ensure the correct device is connected to, and failing if they do not match.

The error fixed itself before I was able to finish writing the script, so I am working on theory without a way to test until I have a situation to test this with again.

Based off of the situation I could test - this is what I have so far:

$HN = Hostname
$IP = ([System.Net.DNS]::GetHostAddresses($HN) | Where-Object {$_.AddressFamily -eq "InterNetwork"} | select-object IPAddressToString)[0].IPAddressToString
$HNAD = (Get-ADComputer $HN).dnshostname
$HNDNS = [System.Net.Dns]::GetHostByAddress($IPAddress).hostname

From there I would have an If statement comparing the two Hostnames to ensure they match, and if they don't - Throw an error. That's easy, but I am not sure if my theory behind how/where the information is pulled from is correct.

Is this completely off base? I know there are a few ways to resolve hostnames and IP addresses, but without a testable situation I don't know what path to take. It seems like it boils down to AD resolving to the wrong device based off of stale DNS information, but I am not 100% sure, I just know being able to compare the two resolutions would help connecting to the wrong device.


Solution

  • I found it best to go with Olaf's recommendation of connecting to the device and then pulling it's COMPUTERNAME variable and comparing to the device you are wanting to connect to.

    $WorkstationDestinationHN = Invoke-command -ErrorAction SilentlyContinue -ComputerName $WorkstationHN -ScriptBlock{$env:COMPUTERNAME}
    

    Then compare them how you see fit. In my case I am gathering more data so I don't want it to stop on error, so set it to silently continue. I had mine in an if then setting triggers for errors after everything is resolved.

    Try
    {
        if ($WorkstationDestinationHN -ne $WorkstationHN)
        {
            $ThrowDestination = 1
            $ThrowError = 1
        }
    #Other if statements detecting errors
    
        if ($ThrowError = 1)
        {
            Throw "Unable to resolve requested information"
        }
    }
    Catch
    {
        if ($ThrowDestination = 1)
        {
            Write-Output "destination device does not match provided information"
        }
    }
    

    When ThrowError is set to 1 it triggers the catch statement. The ThrowDestination variable would then be used to know which error messages need to be thrown in the following catch statement.