Here are some code examples to check if a server is pingable.
CLS
$IP = 123.123.123.123
#Check server by testing RDP port
if(([System.Net.Sockets.TcpClient]::new().ConnectAsync($IP, 3389).Wait(1000)) -eq "True")
{
$True
}
#Test server by sending a ping request (ICMP)
if(([System.Net.NetworkInformation.ping]::new().SendPingAsync($IP).Wait(1000)) -eq "True")
{
$True
}
In the above example, it checks to see if a device is pingable. The answer is almost immediate if the ping is successful, however if a ping is unsuccessful it takes some time before it times out. In our example we set the timeout to 5 seconds “5000” ms, however you can adjust this value as needed.
Another way to check if a server is accessible is by performing a Get-CimInstance as shown below.
if($NULL -ne (Get-CimInstance -ErrorAction SilentlyContinue -ClassName Win32_PingStatus -Filter "Address='$($IP)' AND Timeout=5000").ResponseTime)
{
$True
}
EDIT: 9-12-2024
After some poking around I found a way that seems to be even faster for pinging several devices/IP’s. It uses the same logic, as one of the above examples, but it runs it as a task. From my tests it cuts down runtime by about 3 seconds scanning 1400 servers. (total run time about 5 seconds)
Here is the example:
The code below used the following script as a baseline (Credit to Boe Prox):
SRC: AsyncFunctions/Test-ConnectionAsync.ps1 at master · proxb/AsyncFunctions · GitHub
CLS
$Servers = ((dsquery * -filter "(&(objectClass=Computer)(objectCategory=Computer)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(operatingSystem=*Server*)(!(servicePrincipalName=*MSClusterVirtualServer*)))" -limit 0) | %{ if ($_ -match '^"CN=(.+?),\s*\w{1,2}=') { $matches[1] } }) | sort -Unique
$Task = ForEach ($Server in $Servers)
{
[pscustomobject] @{
Server = $Server
Task = (New-Object System.Net.NetworkInformation.Ping).SendPingAsync($Server,1000)
}
}
Try
{
[void][Threading.Tasks.Task]::WaitAll($Task.Task)
}
Catch {}
$Task | ForEach {
If ($_.Task.IsFaulted)
{
$Result = $_.Task.Exception.InnerException.InnerException.Message
$IPAddress = $Null
}
Else
{
$Result = $_.Task.Result.Status
$IPAddress = $_.task.Result.Address.ToString()
}
$Object = [pscustomobject]@{
Server = $_.Server
IPAddress = $IPAddress
Result = $Result
}
$Object.pstypenames.insert(0,'Net.AsyncPingResult')
$Object | Where-Object { ($_.Result -eq "Success") } | Select-Object -Property Server -ExpandProperty Server
}
If you have other ways to check if a computer is online/accessible remotely, feel free to share your examples.