I was trying to copy some files to a group to a computers. What I’d do is check if the computer is alive first, by doing a network ping. If the computer answered the Ping, then the computer was alive, so I would then copy files to it.
It mostly worked, except when it didn’t. Here is the clue which lead me to the answer:
C:\>ping alfred
Pinging ALFRED [192.168.1.5] with 32 bytes of data:
Reply from 192.168.1.5: bytes=32 time<1ms TTL=128
…
C:\>ping powergirl
Pinging POWERGIRL [192.168.1.5] with 32 bytes of data:
Reply from 192.168.1.5: bytes=32 time<1ms TTL=128
C:\>
The DNS server was returning the same IP address for two different computers. As POWERGIRL was powered on, it answered the Ping request for ALFRED. When I tried to copy to ALFRED, it failed as the file copy was trying to verify that ALFRED was at 192.168.1.5, and it wasn’t.
The cause? The DNS server was retaining IP addresses for 24 hours. Sometimes a computer’s IP will change more often than that. So the DNS server ended up with 2 or more DNS computer records with the same IP.
The fix? Tell the DNS server to only retain DNS records for 2 hours. (for the more technically minded, we adjusted the Time To Live value).
How I originally detected the DNS server was lying to me?
I pinged the computer (ALFRED) to get it’s IP address (192.168.1.5).
I then asked IP address 192.168.1.5 what it’s computer name was. In the example above, it was actually POWERGIRL.
The code to do that is in the Reachable function, below:
Function Reachable(strComputer)
Dim wmiQuery, objWMIService, objPing, objStatus,sIPAddress,sComputerName
wmiQuery = "Select * From Win32_PingStatus Where Address = '" & strComputer & "'"
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set objPing = objWMIService.ExecQuery(wmiQuery)
For Each objStatus In objPing
If IsNull(objStatus.StatusCode) Or objStatus.Statuscode<>0 Then
Reachable = False 'if computer is unreacable, return false
Else
Reachable = True 'if computer is reachable, return true
'wscript.echo strComputer & " : " & objStatus.ProtocolAddress
sComputerName = strComputer
sIPAddress = objStatus.ProtocolAddress
If objStatus.ProtocolAddressResolved <> "" then
wscript.echo strComputer & " : " & objStatus.ProtocolAddressResolved
End If
On Error Resume Next
' ask the computer at IP address sIPAddress, what it's name is.
Set objWMIService2 = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & sIPAddress & "\root\cimv2")
Set colComputers2 = objWMIService2.ExecQuery ("Select * from Win32_ComputerSystem")
For Each objComputer2 in colComputers2
If strComputer <> objComputer2.Name Then
‘ dump out that the computer we PING is not the computer which actually answered.
WScript.Echo strComputer + " : " +objComputer2.Name
Else
‘ the computer which answered is the computer we pinged.
WScript.Echo objComputer2.Name
End if
Next
On Error GoTo 0
End If
Next
End Function