Windows Commands about Networking
Troubleshooting Network Communications
(The above image is from
NetworkComTroubleshooting, there you'll find attached the excel sheet from which it was generated)
About the firewall
To see whether the Windows Firewall is enabled:
netsh advfirewall show allprofile
To disable the firewall for a specific profile (privateprofile, domainprofile, publicprofile):
netsh advfirewall set privateprofile state off
Firewall: Open ports / Allow services
# To open ports (these commands *work for all profiles,* public, private, domain):
netsh advfirewall firewall add rule action=allow protocol=TCP dir=in name="Open Remote Desktop" localport=3389
netsh advfirewall firewall add rule action=allow protocol=UDP dir=out name="Just an Example" localport=6000-7000
# to allow ping
netsh advfirewall firewall add rule name="ICMP Allow incoming V4 echo request" protocol=icmpv4:8,any dir=in action=allow
netsh advfirewall firewall add rule name="ICMP Allow incoming V6 echo request" protocol=icmpv6:8,any dir=in action=allow
# to delete a rule
netsh advfirewall firewall delete rule name="rule name" protocol=udp localport=500
# list of all rules.
netsh advfirewall firewall show rule name=all
Test network connection
PS C:\Users\user> if (TNC www.bing.com –InformationLevel Quiet) {} # BASIC TEST: will ping and return true
PS C:\Users\user> tnc 10.1.11.1 -Port 80 -InformationLevel Detailed
ComputerName : 10.1.11.1
RemoteAddress : 10.1.11.1
RemotePort : 80
NameResolutionResults : 10.1.11.1
sense.lan.enlogic.gr
MatchingIPsecRules :
NetworkIsolationContext : Internet
IsAdmin : False
InterfaceAlias : Ethernet 6
SourceAddress : 10.1.11.233
NetRoute (NextHop) : 0.0.0.0
TcpTestSucceeded : True
Testing if a TCP port is open (or if e.g. a firewall blocks TCP connections)
These commands will attempt to connect to the spefied address, TCP port and report if it succeded or not:
(New-Object Net.Sockets.TcpClient "10.1.11.189", 8080).Connected
True
Test-NetConnection -Port 8080 -ComputerName 10.1.11.189
...
SourceAddress : 10.1.11.233
TcpTestSucceeded : True <---- a connection was made
If you need something
faster or need to test
many ports or
many hosts use this function:
function GetTcpPortState ($hostname,$ports,$timeout=100) {$tcpobj = @{}; $open = @{}; $requestCallback = $state = $null; foreach ($port in $ports) {$tcpobj[$port] = New-Object System.Net.Sockets.TcpClient; $foo = $tcpobj[$port].BeginConnect($hostname,$port,$requestCallback,$state)} Start-Sleep -milli $timeOut; foreach ($port in $ports) {$open=($tcpobj[$port].Connected); $tcpobj[$port].Close(); [pscustomobject]@{port=$port;open=$open}}}
# TEST MANY PORTS
GetTcpPortState mail.doculand.com @(25,80,443,465,587) -timeout 200
# TEST MANY HOSTS AND PORTS
@("142.251.18.26", "142.251.18.27", "142.250.150.26") | %{ GetTcpPortState $_ @(25,80) -timeout 200}
For even more serious work
install nmap on windows which does this and many, MANY more.
Testing every few seconds one or more ports of a host
Define some functions:
function GetTcpPortState ($hostname,$ports,$timeout=100) {
$tcpobj = @{}
$open = @{}
$requestCallback = $state = $null
foreach ($port in $ports) {
$tcpobj[$port] = New-Object System.Net.Sockets.TcpClient
$foo = $tcpobj[$port].BeginConnect($hostname,$port,$requestCallback,$state)
}
Start-Sleep -milli $timeOut
foreach ($port in $ports) {
$open=($tcpobj[$port].Connected)
$tcpobj[$port].Close()
[pscustomobject]@{
port=$port
open=$open
}
}
}
function Test-ManyPorts($HOST_TO_MONITOR, $PORTS_TO_MONITOR, $SLEEP_BETWEEN_TESTS = 60) {
Write-host -For cyan "$(get-date) Checking ports $PORTS_TO_MONITOR of $HOST_TO_MONITOR every $SLEEP_BETWEEN_TESTS seconds"
Write-host -For gray "(V=open X=not open, Printing only changes in ports state)"
Write-host -For gray "(If a port appears not open we failed to connect 4 times)"
$prev_NotOpenPorts = @(-1)
while ($true) {
$StartTime = $(get-date)
$NotOpenPorts = $PORTS_TO_MONITOR
1..4 | ForEach-Object {
if ($NotOpenPorts) {
$state=(GetTcpPortState $HOST_TO_MONITOR $NotOpenPorts -timeout 200)
$NotOpenPorts = ($state | ?{!$_.open}).port
}
}
# without -join "," this does not work (WTF????)
if (($prev_NotOpenPorts -join ",") -ne ($NotOpenPorts -join ",")) {
Write-host -For white -Nonew "$StartTime "
$PORTS_TO_MONITOR | %{
if ($_ -in $NotOpenPorts) {
write-host -for red -Nonew "$_ X "
} else {
write-host -for green -Nonew "$_ V "
}
}
write-host -for white ""
$prev_NotOpenPorts = $NotOpenPorts
}
$elapsedTime = $(get-date) - $StartTime
sleep ([math]::max(0.1, $SLEEP_BETWEEN_TESTS - $elapsedTime.TotalSeconds))
}
}
# Example of how to call the above
Test-ManyPorts "10.30.0.4" @(22001,80,3389) 10
Opening a TCP port waiting for the first connection
YOU HAVE TO CLOSE THE powershell WINDOW
AFTER THIS
$port=8080
$listener = new-object System.Net.Sockets.TcpListener([System.Net.IPAddress]::Any,$port)
$listener.Start()
do { $client = $listener.AcceptTcpClient() # Will block here until connection is established
sleep 1} while ($true)
Enabling remote administration of a server/PC
Netsh advfirewall firewall set rule group="Windows Firewall Remote Management" new enable=yes
Enabling remote event log
Set-NetFirewallRule -DisplayGroup 'Remote Event Log Management' -Enabled True -PassThru | select DisplayName, Enabled
General System info
# are we joined in a domain or not?
if ((Get-WmiObject -Class Win32_ComputerSystem).PartOfDomain) {echo "Part of DOMAIN: $($env:USERDNSDomain)"}
if ((Get-WmiObject -Class Win32_ComputerSystem).Workgroup) {echo "Part of Workgroup: $($env:USERDNSDomain)"}
*CAUTION: When you use netsh the network names may differ from those you see in ipconfig.*
The DNS resolution order, is the same as the routing order. I.E the interface metric ( Lowest metric is Higher priority)
# IP configuration
#==================
ipconfig /all # the old way
netsh interface ip show config # was the new way for a while
netsh interface ip show config | sls "DNS|^[^ ]| IP|^$" # the most important info
# THE REALLY NEW WAY
PS C:\WINDOWS\system32> Get-NetAdapter
Name InterfaceDescription ifIndex Status MacAddress LinkSpeed
---- -------------------- ------- ------ ---------- ---------
Ethernet 4 Broadcom NetXtreme Gigabit 6 Up B8-AC-6F-82-68-DB 1 Gbps
Ethernet 3 Intel(R) Ethernet Ser...#2 5 Disconnected 00-1B-21-8E-EB-F5 0 bps
PS C:\WINDOWS\system32> GIP -Detailed # Alias for Get-NetIPAddress
ComputerName : GS-BDESKTOP
InterfaceAlias : Ethernet 4
InterfaceIndex : 6
InterfaceDescription : Broadcom NetXtreme Gigabit Ethernet
NetAdapter.LinkLayerAddress : B8-AC-6F-82-68-DB
NetAdapter.Status : Up
NetProfile.Name : work.microsoft.com
NetProfile.NetworkCategory : DomainAuthenticated
NetProfile.IPv6Connectivity : Internet
NetProfile.IPv4Connectivity : Internet
IPv6Address : 2001::86eb
IPv6TemporaryAddress : 2001::e7b4
IPv6LinkLocalAddress : fe80::86eb%6
IPv4Address : 192.31.25.52
IPv6DefaultGateway : fe80::8a75:56ff:fe3d:7380
IPv4DefaultGateway : 192.31.25.1
NetIPv6Interface.NlMTU : 1500
NetIPv4Interface.NlMTU : 1500
NetIPv6Interface.DHCP : Enabled
NetIPv4Interface.DHCP : Enabled
DNSServer : 158.55.16.178
PS C:\WINDOWS\system32> $Object = GIP 'Ethernet 4'
PS C:\WINDOWS\system32> $Object.IPv4DefaultGateway
# For hyper-v
PS C:\Users\Administrator> Get-VMNetworkAdapter -VMName DemoVM1
Name IsManagementOs VMName SwitchName MacAddress Status IPAddresses
---- -------------- ------ ---------- ---------- ------ -----------
Network Adapter False DemoVM1 BackToBack 00155D3AE401 {Ok} {192.168.0.3}
What programs/services are listening for TCP connections on the network?
The new way (RemoteAddress -ne '::' filters out IPv6)
Get-NetTCPConnection -State Listen | Select-Object -Property *,@{'Name' = 'ProcessName';'Expression'={(Get-Process -Id $_.OwningProcess).Name}} | select -Property LocalPort,ProcessName,OwningProcess,RemoteAddress | ?{$_.RemoteAddress -ne '::'} | ft
If you don't have PowerShell
netstat -ano
is good enough
Info about DHCP
# basic stats Get-DhcpServerv4Lease -ScopeId 192.168.18.0
Get-DhcpServerv4ScopeStatistics | ft
# free ip addresses DhcpServerv4FreeIPAddress -ScopeId 192.168.18.0 -StartAddress 192.168.18.1 -NumAddress 255
# reserved IPs Get-DhcpServerv4Reservation -ScopeId 192.168.18.0
# how many smartphones $smartphones=(Get-DhcpServerv4Lease -ScopeId 0 | ?{$x=$_.hostname; $x -like '*galaxy*' -or $x -like '*iphone*' -or $x -like '*redmi*' -or $x -like '*huawei*' -or $x -like '*mi8lite*'} | Measure-Object).count; echo "$smartphones smartphones connected"
About the WiFi
Get the SSID of the WIFI you are connected to:
netsh wlan show interfaces | select-string '\bSSID'
(From
https://www.windowscentral.com/how-manage-wireless-networks-using-command-prompt-windows-10 or
https://www.webcitation.org/72HafgAdX )
Netsh WLAN show profiles
Netsh WLAN show drivers
Netsh WLAN show wirelesscapabilities
Netsh WLAN show interfaces
Netsh WLAN show profile name="Profile_Name" key=clear
Netsh WLAN show WLANreport
Netsh WLAN set profileparameter name="Profile_Name" connectionmode=manual
Netsh WLAN set profileparameter name=" Profile_Name" connectionmode=auto
Netsh WLAN export profile name="Profile_Name" key=clear folder="Folder_Path"
Netsh WLAN add profile filename="File_Path.XML"
Packet capturing (A.K.A. network sniffing, packet tracing)
Realtime for Win10 version>=2004
Use pktmon like in this example where we trace all packets to/from tcp/udp port 3389 or to trace ping packets:
# trace RDP port
pktmon filter add -p 3389
pktmon start --etw -p 0 -l real-time
# trace ping packets
pktmon filter add PingFilter -t ICMP
pktmon start –etw –log-mode real-time
More info at
https://www.bleepingcomputer.com/news/microsoft/windows-10-quietly-got-a-built-in-network-sniffer-how-to-use/
Realtime for Win10 version<2004
Try windump + npcap
Non realtime for all versions
# PowerShell
netsh trace start capture=yes Ethernet.Type=IPv4 IPv4.Address=172.16.0.3 tracefile=c:\temp\trace1.etl; pause; netsh trace stop
# IPv4.SourceAddress=(192.168.1.7,192.168.1.9)
# IPv4.DestinationAddress=!(192.168.1.10)
# Ethernet.Address=00-0D-56-1F-73-64
# CaptureInterface=”Local Area Connection”
# protocol=UDP # only UDP traffic
# protocol=1 # only ICMP traffic (e.g. pings)
# maxSize=1 # max 1 MByte capture
How to open the resulting trace.etl file:Open Microsoft Network Monitor 3.4. and before opening the file go to Tools > Options > Parser Profiles > Select
“Windows Parser” and set it as Active (top right corner)
Or use Microsoft Message Analyzer which is the successor of Network Monitor (haven't tried it though)
*CAUTION: When you use netsh the network names may differ from those you see in ipconfig.*
The DNS resolution order, is the same as the routing order. I.E the interface metric ( Lowest metric is Higher priority)
# IP configuration
#==================
ipconfig /all # the old way
netsh interface ip show config # the new way
netsh interface ip show config | sls '^Config|IP A|^$' # just the net. names
netsh interface ip show config | sls "DNS|^[^ ]| IP|^$" # the most important info
# SAVE AND RELOAD CURRENT NETWORK CONFIGURATION
# (test it beforehand because netsh exec some times fails on Greek Windows)
#==============================================
netsh interface dump > c:\netcfg.dat
netsh exec c:\netcfg.dat
# Change DNS server
#===============================
Get-DNSClientServerAddress | ?{$_.ServerAddresses} # to see all possible Interface indexes
Set-DNSClientServerAddress -InterfaceIndex $index -ServerAddresses ("10.1.11.1")
# In this more complex example we change the DNS server of the interface with IP like 10.30.32.*
$IfaceIP='10.30.32.*';$ToDNS="10.1.11.1"; $index = (gip | select -Property IPv4Address, InterfaceIndex, DNSServer | ?{$_.IPv4Address.IPAddress -like $IfaceIP}).InterfaceIndex; if ($index) {echo "Setting DNS server for iface $index to $ToDNS"; Set-DNSClientServerAddress -InterfaceIndex $index -ServerAddresses ($ToDNS)} else {"No interface with $IfaceIP found"}
# old(DOS) way (with netsh)
netsh interface ip delete dns "Local Area Connection" all # delete existing DNS
netsh interface ip set dns "Local Area Connection" static 10.2.0.1 # add the 1st one
netsh interface ip add dns "Local Area Connection" 10.10.10.3 index=2 # add another one
netsh interface ip set dns "Local Area Connection" dhcp # set DNS to auto (from DHCP)
# Change IP address
#=================
netsh interface ip set address "Local Area Connection" static 10.1.11.30 255.255.255.0 10.1.11.1
netsh interface ip set address "Local Area Connection" dhcp
# View/Change Default Gateway (and metric)
#==========================================
route print | sls '0\.0\.0\.0.*0\.0\.0\.0' # view default Gateway
route print # view complete routing table
# add a new default GW
route add 0.0.0.0 mask 0.0.0.0 10.1.11.1
# change the metric (priority) of the default GW route for interface "Ethernet"
netsh int ip set interface interface="Ethernet" metric=100
# restore the metric to automatic
netsh int ip set interface interface="Ethernet" metric=automatic
# ENABLE/DISABLE interface
#==========================
netsh int set interface name="Local Area Connection 3" admin=disabled
netsh int set interface name="Local Area Connection 3" admin=enabled
# Change Interface Metric
Get-NetIPInterface
Set-NetIPInterface -InterfaceIndex 21(from the first colume) -InterfaceMetric 10
#View the Interface Metric
Get-NetIPInterface | Select-Object -Property InterfaceAlias, InterfaceMetric | Sort-Object -Property InterfaceMetric
# To change the adapter to automatic
Set-NetIPInterface -InterfaceIndex 21 -AutomaticMetric enabled
#Set DNS Suffix and Registration
#Finds all the adapter with a valid IP address
$networkConfig =
Get-WmiObject Win32_NetworkAdapterConfiguration -filter "ipenabled = 'true'"
#Sets the DNS Suffix for this connection
$networkConfig= .SetDnsDomain(
"clients.ad.company.com" )
#Checks the two boxes
$networkConfig= .SetDynamicDNSRegistration( $true ,$true)
ipconfig /registerdns

#View the DNS suffix search list
Get-DnsClientGlobalSetting
#Set the DNS suffix search list
Set-DnsClientGlobalSetting -SuffixSearchList @("corp.contoso.com", "na.corp.contoso.com")
About Network Location Awareness (NLA)
Find out what our current network location is set to:
PSH> Get-NetConnectionProfile
Name : Unidentified network
...
InterfaceIndex : 18
NetworkCategory : Public
...
Let's switch it to Private:
Set-NetConnectionProfile -InterfaceIndex 18 -NetworkCategory Private
You can get an overview of the NLA of all networks with:
gip -Detailed | %{ "$($_.NetProfile.NetworkCategory)`t.$($_.IPv4Address.IPAddress)`t'$($_.InterfaceAlias)'`t'$($_.InterfaceDescription)'"}
If your D.C. thinks it's Network type is not "Domain"
This can be caused if the
NLA
service
starts before the domain is available
. In this case the public or private network is chosen. If that's your problem the easy/manual remedy is to either restart the NLA service (
PS> Restart-Service -f nlasvc
) or disconnect / reconnect the network.
Proper solution: It may help to set the NLA Service to delayed start.
More Solutions
Tests, benchmarks, troubleshouting
Assess the quality of Internet connections (long term)
Using out-pingstats
powershell -exec bypass -c ". {iwr -useb https://raw.githubusercontent.com/ndemou/Out-PingStats/main/Out-PingStats.ps1}|iex"
Alternative way (2023-Jun)
(TODO:
1) if fping is not available ping.exe to 1.1.1.2 is good enough
2) print 20 times then return at start of line, do it 6 times and finaly return to start of line and print the graph
3) print and graph the p98 instead of the max
4) make the graph for loss twice as wide because 1% loss is almost invisible)
You need to download fping.exe and cygwin.dll from this wikipage first. Place them in any directory you like. CD to that directory and run this:
$blockCharacters = [array](0x258F..0x2588 | ForEach-Object { [char]$_ })
$blockCharacters = @(" ") + $blockCharacters
function horiz_bar($value) {
$fullBlocks = [int][math]::Floor($value / 8)
$remainder = $value % 8
$progressBar = ($blockCharacters[8].ToString() * $fullBlocks) + $blockCharacters[$remainder]
$progressBar
}
function color_from_value($value, $ref, $x1, $x2, $x3, $x4) {
if ($value -gt $ref * $x4) {$color="red"
} elseif ($value -gt $ref * $x3) {$color="yellow"
} elseif ($value -gt $ref * $x2) {$color="DarkYellow"
} elseif ($value -gt $ref * $x1) {$color="cyan"
} else {$color="green"}
$color
}
function Test-Internet($MAX_GOOD_RTT=20) {
$all_hosts = @"
adu.com aau.com eb.com alj.com ao.com afg.com ccm.com aip.com cbv.com bqs.com pq.com apr.com tn.com btc.com abt.com zb.com bvs.com cm.com md.com ani.com btq.com ads.com ef.com aex.com aje.com aae.com bts.com cgr.com arv.com cdg.com zl.com atl.com
akc.com av.com amf.com akk.com tu.com acz.com bom.com rv.com aok.com ci.com anf.com amh.com byl.com aaw.com vw.com car.com aue.com cdj.com ago.com yg.com bpj.com ix.com bzb.com bov.com wg.com aqb.com mx.com apm.com bpn.com azd.com bfa.com jy.com
ky.com alp.com aoi.com wz.com apu.com no.com aop.com akx.com bo.com ada.com pt.com bmf.com ahr.com atr.com rl.com ka.com agl.com uj.com bwo.com brc.com mu.com cg.com cfk.com kj.com ceb.com bwb.com box.com cdq.com adk.com bwz.com cdp.com ww.com
bwv.com cbm.com ov.com wy.com lg.com abl.com ry.com kw.com arq.com px.com agt.com bum.com awl.com bv.com ej.com xi.com aic.com byg.com bak.com buq.com mz.com hr.com bns.com nj.com arb.com cby.com abc.com ev.com boz.com aqx.com bgt.com axp.com
es.com bmg.com ck.com btx.com cds.com cgt.com ft.com cb.com cbs.com pu.com acc.com cgg.com byj.com agu.com qa.com vy.com cfv.com avd.com mj.com qp.com bxa.com ajl.com bzz.com bjj.com alc.com apg.com cd.com apl.com bwn.com jm.com agh.com and.com
"@
$min=9999; $max=0; $lost=0; $count=0
$now = (get-date)
$prev_minute = $now.minute
$all_hosts = ($all_hosts -replace " *", " " -replace "^ *" -replace " *$")
$hosts_per_set = (($all_hosts -split "`n")[0].split(" ")).count
Write-Host -for cyan "Pinging $hosts_per_set hosts in parallel every ~1sec."
Write-Host -for cyan "Green dots mean that >=90% of hosts responded and RTT was <$($MAX_GOOD_RTT)ms."
Write-Host -for cyan "Something like x(y) means RTT was x msec and y hosts did not respond."
Write-Host -for cyan "Every 2min we print statistics and one bar for loss and one for max RTT"
$hhmm = $now.ToString("HH:mm ")
write-host -nonewline -for gray "$hhmm "
while ($true) {
$all_hosts -split "`n" | %{ $hosts_set=$_.split(" ")
$StartTime = $(get-date)
try {
$out1 = (& .\fping.exe -r0 -C1 $hosts_set 2>$null)
} catch {
Write-Host -for yellow "Please cd to the directory with fping.exe and cygwin.dll and run Test-Internet again"
}
$out2 = ($out1 | sls ' ms ') -replace "^.*bytes, " -replace ' ms .*'
if ($out2) {
$rtt = ($out2 | %{[int]$_} | sort | select -first 1)
if ($rtt -lt $min) {$min=$rtt}
if ($rtt -gt $max) {$max=$rtt}
$lost_hosts = ($hosts_set.count - $out2.count)
# About the usual values of $lost_hosts:
# On a busy line, pinging 32 hosts,
# 50% of values are <=17
# 90% of values are <=26
# That's why I only bother to print $lost_hosts if it is >50% of total
# And why if RTT is good I ignore up to 26 lost hosts
if (($rtt -lt $MAX_GOOD_RTT) -and ($lost_hosts -le 26)) {
if ($last_char -eq ".") {
write-host -for green -nonewline "`b:"
$last_char=":"
} else {
write-host -for green -nonewline "."
$last_char="."
}
} else {
$last_char="?"
$color = (color_from_value $rtt $MAX_GOOD_RTT 1 2 4 8)
write-host -nonewline -for $color "$rtt"
if ($lost_hosts -gt $hosts_per_set*0.5) {
write-host -nonewline -for darkgray "($lost_hosts) "
} else {
write-host -nonewline " "
}
}
} else {
$last_char="?"
write-host -nonewline -for black -back red "XXX"
write-host -nonewline " " # reset color
$lost += 1
}
$count += 1
$now = (get-date); $elapsedTime = $now - $StartTime
# if ($elapsedTime.TotalMilliseconds -gt 999) {write-host -nonewline -for black -back gray " $($elapsedTime.TotalMilliseconds) "}
sleep ([math]::max(0,(1000-$elapsedTime.TotalMilliseconds))/1000)
$minute = $now.minute
if ($minute -ne $prev_minute) {
$prev_minute = $minute
$last_char="?"
if ($minute % 2 -eq 0) {
write-host ""
write-host -for white -nonewline "$hhmm lost=$('{0,3}' -f $lost)/$('{0,3}' -f $count),"
write-host -for white -nonewline " min=$('{0,3}' -f $min), Max=$('{0,3}' -f $max) L:"
$lost_bar = (horiz_bar ([Math]::Min(2*20, [int](2*$lost*100/$count))))
$lost_bar = $lost_bar.PadRight(5, ' ')
$max_bar = (horiz_bar ([Math]::Min(16*$MAX_GOOD_RTT, [int]($max))))
$max_bar = $max_bar.PadRight(16*$MAX_GOOD_RTT/8, ' ')
write-host -back darkgray -for red -nonewline $lost_bar
write-host -for white -nonewline " M:"
$color = (color_from_value $max $MAX_GOOD_RTT 1 2 4 8)
write-host -back darkgray -for $color -nonewline $max_bar
write-host -for white ""
$hhmm = (Get-Date).ToString("HH:mm ")
write-host -nonewline -for gray "$hhmm "
$min=9999; $max=0; $count=0; $lost=0
} else {
write-host ""
write-host -nonewline -for gray "$((Get-Date).ToString("HH:mm ")) "
}}}}}
Test-Internet
#
Assess the quality of connection to specific host (long term)
# download
powershell -exec bypass -c ". {cd '$Env:USERPROFILE'; iwr -useb https://raw.githubusercontent.com/ndemou/Out-PingStats/main/Out-PingStats.ps1 -OutFile Out-PingStats.ps1}"
# run
powershell -exec bypass -c "cd '$Env:USERPROFILE'; .\Out-PingStats.ps1 -PingsPerSec 4 $(read-host 'Enter IP to ping')"
For more info and to better understand the output see
https://github.com/ndemou/Out-PingStats
quick'n'dirty graph of ping times
$ip="google.gr"; $msec_per_bar= 2; $host.ui.RawUI.WindowTitle="pinging $ip"; ping -t $ip | %{ if ($_ -like '*time=*') {$ms=($_ -replace '^.*time=','' -replace '[^0-9.].*',''); $bar=("#"*($ms/$msec_per_bar)); ":$($ms):$bar"} else {$_} }
Report every Nsec and keep detailed logs
Assess the quality of the network connection to $target by displaying and saving ping statistics every 10sec. It saves to a text file named ...ping.txt.
$target="8.8.8.8"; $every_sec=10; $fname="$target.$(Get-Date -Format 'dd-MM-yy_HH.mm.ss').ping.txt"; echo "Please wait... BTW I'm logging to $fname"; while (1) { $text = ping -n $every_sec $target | sls -Pattern loss,Minimum | % {$_ -replace "Packets.* Lost", "Lost" -replace "imum","" -replace " \(.*loss\)","" }; $text = $text.Split("`n`r"); $text = $text -join "" ; $text = $text -replace " "," "; echo "$(Get-Date -Format "HH:mm:ss"):$text" | Tee-Object -Append -FilePath "$fname"; sleep 0.9}
OR THE SAME BUT FOR OLD (e.g. WIN7) VERSIONS OF POWERSHELL
$target="8.8.8.8"; $every_sec=10; $fname="$target.$(Get-Date -Format 'dd-MM-yy_HH.mm.ss').ping.txt"; echo "Please wait... BTW I'm logging to $fname"; while (1) { $text = ping -n $every_sec $target | select-string -Pattern loss,Minimum | % {$_ -replace "Packets.* Lost", "Lost" -replace "imum","" -replace " \(.*loss\)","" }; echo "$(Get-Date -Format "HH:mm:ss"):$text" | Tee-Object -Append -FilePath "$fname"; sleep 0.9}
How to evaluate results
To see all times where packets were lost:
cat <FILENAME>.ping.txt | sls "Lost = [1-9]"
To convert the file to csv (semicolon delimited) in order to open it with excel:
cat <FILENAME>.ping.txt | % {$_ -replace ': Lost = *',';' -replace 'ms,',',' -replace 'ms$','' -replace ". [A-Za-z ]*= ",";" } > file.csv
And this is how you calculate some useful statistics from the files that are created:
$file= ".\8.8.8.8.13-06-21_14.30.53.ping.txt" ; $total=0; $lost=0; cat $file| %{$total += 10; $_} | sls 'Lost = 0,' -NotMatch | %{ $_ -replace ',
Min.*','' -replace ', *','' -replace '^. = ',''} | %{ $lost += $_}; $perc=100*$lost/$total; echo "$file, Lost $lost / $total = $perc%"
.\8.8.8.8.13-06-21_14.30.53.ping.txt, Lost 45 / 29460 = 0.152%
$file=".\192.168.1.254.13-06-21_14.29.47.ping.txt"; $total=0; $lost=0; cat $file| %{$total += 10; $_} | sls 'Lost = 0,' -NotMatch | %{ $_ -replace ',
Min.*','' -replace ', *','' -replace '^. = ',''} | %{ $lost += $_}; $perc=100*$lost/$total; echo "$file, Lost $lost / $total = $perc%"
.\192.168.1.254.13-06-21_14.29.47.ping.txt, Lost 5 / 29740 = 0.016%
$file= ".\8.8.8.8.13-06-21_14.30.53.ping.txt"; $out=0; $max_deviation=10; $count=1; $sum=0; cat $file | sls Average | %{$_ -replace '^.* Average = ' -replace 'ms',''} | %{$sum += $_; $count +=1}; $avg=[int]($sum/$count); cat $file | sls Average | %{[int]($_.line -replace '^.* Average = ' -replace 'ms','')} | ?{ [int]$_ -lt $avg-$max_deviation -or [int]$_ -gt $avg+$max_deviation} | %{ $out+=1}; "$file, average of all averages is ${avg}ms"; $perc= [math]::Round( 100*$out/$count,2); " $out out of $count groups ($perc%) have an average outside $avg+/-${max_deviation}msec"
.\8.8.8.8.13-06-21_14.30.53.ping.txt, average of all averages is 27ms
5 out of 2929 groups (0.17%) have an average outside 27+/-10msec
Test DNS server
function flood_test_DNS_server($MAX_NORMAL_RESP_TIME, $DNS_SERVER="") {
<# Queries the DNS server with 6 different domains and as soon as it gets a response it queries again
Prints response time. Highlights responses that take more than MAX_NORMAL_RESP_TIME
EXAMPLE OUTPUT:
08/29/2022 10:50:32 abc.com time=319 # response time is over MAX_NORMAL_RESP_TIME
08/29/2022 10:50:33 bca.com time=324 # ...
08/29/2022 10:50:35 cab.com ****TIMEOUT**** # Timeout
# when response time is less than MAX_NORMAL_RESP_TIME:
08/29/2022 10:50:36 abc(27) bca(25) cab(24) abg(24) bga(23) gab(24) abc(23) bca(24) cab(23) abg(23) bga(23) ...
#>
function next_domain($dom) {$dom=$dom="$($dom[1])$($dom[2])$($dom[0])"; if ($dom -eq "abc") {$dom="abg"} else {if ($dom -eq "abg") {$dom="abc"}}; $dom}
$dom="abc"; while ($true) {
$ts = (get-date); $msec = (Measure-Command {$ret=(nslookup "$($dom).com" $DNS_SERVER 2>$null | select-string Address )}).totalmilliseconds; $msec=[int]$msec
if (!($ret)) {
write-host ""; write-host "$ts $dom ****TIMEOUT****"
} else {
if ($msec -lt $MAX_NORMAL_RESP_TIME) {
write-host -nonewline "$dom($msec) "
} else {
write-host ""; write-host "$ts $($dom).com time=$msec"}
}
$dom = (next_domain $dom)}
}
flood_test_DNS_server 200 10.1.11.1
HTTP ping (an HTTP server that responds with OK and a client that keeps requesting a response)
The server
It responds by sending back 10 times OK with a small delay before everyone of them
If you set the sleep_time to 1000msec it will take 10secs to respond
$sleep_time=100 # ms to wait between everyone of the 10 OKs
param([int]$port=8384, [string]$message="OK") #
The client
function main() {
$server="wiki.enlogic.gr:8384" #
Other
Commands equivalent to well known linux ones
Linux |
Windows |
dig -x 1.1.1.1 |
Resolve-DnsName -Name 1.1.1.1 -Type PTR |
DHCP Server statistics and smart phones
PS C:\Users\Administrator> do {$date=(Get-date); $perc=(Get-DhcpServerv4ScopeStatistics).PercentageInUse; $smartphones=(Get-DhcpServerv4Lease -ScopeId 0 | ?{$x=$_.hostname; $x -like '*galaxy*' -or $x -like '*iphone*' -or $x -like '*redmi*' -or $x -like '*huawei*' -or $x -like '*mi8lite*'}); $phone_count = ($smartphones | Measure-Object).count; echo "$date $perc% of IPs are in use, I guess there are $phone_count smartphones connected"; Write-Host -ForegroundColor cyan "List of devices that I _guess_ are smartphones based on host name"; $smartphones | Sort-Object LeaseExpiryTime| ft -Property Hostname,LeaseExpiryTime; sleep 3600 } while ($true)
Example output
05/04/2022 13:49:32 42.51968% of IPs are in use, I guess there are 7 smartphones connected
List of devices that I _guess_ are smartphones based on host name
Hostname LeaseExpiryTime
-------- ---------------
iPhone--Chris 5/5/2022 9:00:03 πμ
Galaxy-Note8 5/5/2022 1:08:06 μμ
MI8Lite-MI8Lite 5/5/2022 1:08:34 μμ
Galaxy-A30s 5/5/2022 1:09:26 μμ
RedmiNote8Pro-RedmiN 5/5/2022 1:14:49 μμ
HUAWEI_P9_lite 5/5/2022 1:17:15 μμ
Galaxy-A10 5/5/2022 1:30:27 μμ
What is my ip address:
Invoke-WebRequest icanhazip.com # what is my IP address from powershell
curl icanhazip.com # what is my IP address from modern powershell and from linux