Windows Commands about Networking

Troubleshooting Network Communications

d65f4a396e082406a11924b437f0be8f.png

(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

Gathering information

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)"}

Basic IP configuration information

*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
40f53ce404965cfb2317e60228e663ab.png
#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
Topic revision: r47 - 25 Jan 2025, NickDemou
Copyright © enLogic