0

We need to change DNS configuration for several servers, before I do that I need to test DNS ports on those servers. The problem is that our servers have multiple NICs, so we need to ensure that the DNS ports test go through a specific NIC, in this case would be the NIC that has DNS configured already.

So, we need to retrieve the NICs list, identify which one has DNS configured and then use that specific NIC to perform the port test to the new DNS servers and check if it is Ok/NOTOK.

The second problem is that our network ranges from Windows 2003 to Windows 2019, so the solution must work through different PowerShell versions ranging from 2.0 to the latest.

With more recent PowerShell versions this wouldn't be a problem, but since we have PS 2.0 and up, the scenario changes.

Anyone has or knows any example out there for this task?

Thank you.

J_PT
  • 479
  • 4
  • 22
  • What have you tried so far? – Jawad Feb 18 '20 at 21:43
  • I can get the nic index with dns configured, but I'm searching for a lib that I can use in powershell 2.0 and up to test connectivity using that nic – J_PT Feb 18 '20 at 22:38

1 Answers1

1

The cmdlet,

Test-Connection

does provide a mechanism for this use case.

Test-Connection -Source 'SomeIPA' -Destination 'SomeDest'

Native ping in any OS provides this as well via the source switch.

You can get InterfaceIndex using

Get-Netadapter

cmdlet in recent versions of PowerShell. ---

Get-NetAdapter -Physical | Where Status -eq 'up' 

--- below v3, you'd do ---

netsh interface ipv4 show interfaces 

--- or ---

Get-WmiObject -Class  win32_networkadapter 

Any connectivity test will only occur with a nic that has connectivity and is properly routed. There are several articles and Q&A's that talk to your use case. A quick web search will show them to you. 'ping using a specific nic'

Examples:

Ping from specific network adapter on Windows

The adapter chosen is based on the routing tables. You can examine the routing tables by running 'route print' or 'netstat -r'. Each entry will have a metric which dictates the weighting of the route - lower numbers are preferred. You can manipulate the routing table with the 'route' command. route /? for details.

route add (destination subnet) MASK (destination subnet mask) (gateway) IF (interface)

Probably easier is to use the -S switch, which lets you specify the source IP address (see ping /? for more infos).

Another thing you can do is change the binding order, which meets your "option to prefer one adapter over the other". Although it varies from Windows OS to OS, it is in a similar location as this example: For Windows 7 you right click on Network, and click properties. Then you click on ""Change adapter settings". Then click on the menu Advanced>Advanced Settings and move the connection you want to have priority to the top.

From Windows 7 (Version 6.1 Build 7601: Service Pack 1) ping /? Usage: ping [-t] [-a] [-n count] [-l size] [-f] [-i TTL] [-v TOS] [-r count] [-s count] [[-j host-list] | [-k host-list]] [-w timeout] [-R] [-S srcaddr] [-4] [-6] target_name

Ping using specific gateway interface or source IP address

Ping using specific source IP address One can set socket stuff. The syntax is:

ping -S ip dest
ping -S 192.168.2.24 www.cyberciti.biz
ping -c 4 -S 10.207.0.54 1.1.1.1

Can I try to ping a website through a specific adapter?


OK, missed the Port thing, but, Test-NetConnection is not in legacy PowerShell period, so not an option, and it does not provide a source switch either anyway.

(Get-Command Test-Connection).Parameters.Keys
AsJob
DcomAuthentication
WsmanAuthentication
Protocol
BufferSize
ComputerName
Count
Credential
Source
Impersonation
ThrottleLimit
TimeToLive
Delay
Quiet
Verbose
Debug
ErrorAction
WarningAction
InformationAction
ErrorVariable
WarningVariable
InformationVariable
OutVariable
OutBuffer
PipelineVariable

(Get-Command Test-NetConnection).Parameters.Keys
ComputerName
TraceRoute
Hops
CommonTCPPort
Port
DiagnoseRouting
ConstrainSourceAddress
ConstrainInterface
InformationLevel
Verbose
Debug
ErrorAction
WarningAction
InformationAction
ErrorVariable
WarningVariable
InformationVariable
OutVariable
OutBuffer
PipelineVariable

You could take the route of using the .Net libraries. Which is how it's been documented in legacy PowerShell. Using stuff like ...

--- New-Object Net.Sockets.TcpClient ---

$tcpObj = New-Object Net.Sockets.TcpClient
$tcpObj.Connect($Ipaddress,$Port)

More info on that namespace is here:

https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.tcpclient?view=netframework-4.8

... combining the results from ping or Test-Connection and piping that to Net.Sockets to deal with the port check.

For example (since this was sort of interesting I threw this together and tested it - so I know it works - well not on W2K3 as I've had none of those in over a decade.):

Clear-Host
$SourceIpa = 'SomeSourceNicIpa'
$TargetDestination = 'Stackoverflow.com'
$TargetResponseCount = 1
$DestinationPort = 443

try
{
    $DestinationIpa = (Test-Connection -Source $SourceIpa -ComputerName $TargetDestination -Count $TargetResponseCount).ipv4address.ipaddressToString
    $tcpObj = New-Object Net.Sockets.TcpClient($DestinationIpa,$DestinationPort)

    if($tcpObj -ne $null)
    {
        "Using the source $SourceIpa. The port $DestinationPort on destination $TargetDestination is open."
        $tcpObj.close()
    }
}
catch
{
    Write-Warning -Message "Using the source $SourceIpa. The port $DestinationPort on destination $TargetDestination is not open."
    $tcpObj.close()
}

And a similar approach could have been done with ping and the .Net namespace as well.

E_net4
  • 27,810
  • 13
  • 101
  • 139
postanote
  • 15,138
  • 2
  • 14
  • 25
  • The solution must work on Windows 2003 as I said at the beginning. I can get the adapter the problem is using a test connections command that uses that interface. Ping is not the same as testing ports – J_PT Feb 19 '20 at 14:36
  • From my tests, the -S parameter in ping for windows 2003 only applies to IPV6, the -Source parameter from Test-Connection applies to the names of the computers where the ping originates, not interface/IP, so this will also not work. Regarding to "Net.Sockets.TcpClient", yes I'm using it but the problem remains, is not bindable to a specific NIC which is my main problem. The most promising that I found was combining the Net.IPEndPoint with Net.Sockets.TcpClient but still unable to bind it to a specific NIC – J_PT Feb 19 '20 at 21:55
  • I finally got IPEndPoint working, I need to perform more tests, but so far works great with 2003. The solution is simple using a IPEndPoint object and pass it as a constructor argument to the TcpClient, after that is just a matter of handling invalid addresses that may be thrown to the IPEndPoint, a try/catch block should solve this problem easily. – J_PT Feb 19 '20 at 22:49
  • Glad you got something useable. Legacy Windows is a pain, and to date, I know why folks keep it, just like those WinXP folks, but still. Well, you know what I mean. – postanote Feb 19 '20 at 23:16