Windows network troubleshooting commands cheat sheet
- Piping the Output to Search
- Ping an IP Address (by default 4 pings are sent)
- Traceroute to a Given IP Address
- Connect via TCP to a Given Host/Port
- Run TCP Port Scanner for a Host
- Download File via HTTP/HTTPS
- Show Routing Table of the Local Host
- Resolve a Domain Name
- Show Windows Firewall Status for an Active Profile
- Show Interfaces and their Status
- Show Full Interface Parameters including MTU
- Show All Network Connections with Ports and IPs
- Show ARP table
- Show IPv6 Neighbors Table
- List of Installed Patches and Hotfixes
- Show Running Services
- Show Current User
- Show Time Zone Set and Current Time
- Show Hosts Currently Visible and Active on local Host
- Show Whether RDP is Enabled on Local Host
- Show on What Port RDP is Enabled
- Show Installed PowerShell Version
- Related
Piping the Output to Search
In all PowerShell commands below, we can pipe the output of any command to ` | Out-String -Stream | Select-String "search_string"` to search for a specific string/value. E.g.:
To search/show only connections to/from port 443:
Get-NetTCPConnection | Out-String -Stream | Select-String "443"
To search/show only route(s) to 10.0.0.33:
Get-NetRoute | Out-String -Stream | Select-String "10.0.0.33"
Ping an IP Address (by default 4 pings are sent)
ping 8.8.8.8
Test-Connection 8.8.8.8
Set packet size larger than default 32 bytes
|
Note
|
Windows will add 8 bytes of ICMP header to the custom size we specify |
ping -l 1200 8.8.8.8
Test-Connection 8.8.8.8 -BufferSize 1200
Send n number of pings
ping -n 1000 google.com
Test-Connection google.com -Count 1000
Send pings non-stop
ping 8.8.8.8 -t
-
Older PowerShell up to version 7 (Windows 11 has version 5.1 by default):
Test-Connection 8.8.8.8 -Count 10000
-
Powershell 7 or newer:
Test-Connection 8.8.8.8 -Repeat
Network MTU maximum size path discovery (PMTU) testing with ping
Here I start pinging with 1400 bytes size, adding each time 20 bytes up to 2500 bytes:
for /L %A in (1400,20,2500) do ping -f -l %A -n 2 8.8.8.8
Sweep Ping All Hosts in a Subnet (CIDR)
Here, I am pinging all hosts in the network 192.168.3.0/24, sending just 1 ICMP packet to each, and showing only results with Reply.
for /L %i in (1,1,254) do @ping -n 1 192.168.3.%i | find "Reply"
|
Note
|
PowerShell below is to be saved in a file and run like: powershell -ExecutionPolicy Bypass -File .\sweep.ps1 192.168.17.0/24
|
<#
.SYNOPSIS
Ping-sweep a network given in CIDR notation and list only hosts that respond.
.PARAMETER Cidr
Network in CIDR notation, e.g. 192.168.17.0/24
.PARAMETER TimeoutMs
Reply timeout per host in milliseconds (default 1000).
.PARAMETER ResolveHostname
Also perform a reverse-DNS lookup for each responding host (slower).
.EXAMPLE
.\Ping-Sweep.ps1 192.168.17.0/24
.EXAMPLE
.\Ping-Sweep.ps1 10.0.0.0/22 -TimeoutMs 500 -ResolveHostname
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, Position = 0)]
[string]$Cidr,
[int]$TimeoutMs = 1000,
[switch]$ResolveHostname
)
# ---------- Parse the CIDR ----------
if ($Cidr -notmatch '^\d{1,3}(\.\d{1,3}){3}/\d{1,2}$') {
throw "Invalid CIDR '$Cidr'. Expected format like 192.168.17.0/24"
}
$ipText, $prefixText = $Cidr -split '/'
$prefix = [int]$prefixText
if ($prefix -lt 0 -or $prefix -gt 32) {
throw "Prefix length must be between 0 and 32 (got $prefix)."
}
$ipBytes = [System.Net.IPAddress]::Parse($ipText).GetAddressBytes()
[Array]::Reverse($ipBytes)
$ipInt = [BitConverter]::ToUInt32($ipBytes, 0)
if ($prefix -eq 0) {
$mask = [uint32]0
} else {
$mask = [uint32]::MaxValue -shl (32 - $prefix)
}
$invertedMask = $mask -bxor [uint32]::MaxValue
$network = $ipInt -band $mask
$broadcast = $network -bor $invertedMask
function ConvertTo-IPAddress([uint32]$Value) {
$b = [BitConverter]::GetBytes($Value)
[Array]::Reverse($b)
return ([System.Net.IPAddress]$b).ToString()
}
# ---------- Build the list of targets ----------
$targets = @()
$hostBits = 32 - $prefix
if ($hostBits -ge 2) {
for ($i = $network + 1; $i -lt $broadcast; $i++) {
$targets += ConvertTo-IPAddress $i
}
} else {
for ($i = $network; $i -le $broadcast; $i++) {
$targets += ConvertTo-IPAddress $i
}
}
Write-Host "Sweeping $Cidr -> $($targets.Count) host(s)..." -ForegroundColor Cyan
# ---------- Concurrent ping sweep ----------
# One Ping object per host: each Ping allows only ONE async call at a time.
$jobs = @()
foreach ($ip in $targets) {
$pinger = New-Object System.Net.NetworkInformation.Ping
$jobs += [PSCustomObject]@{
IP = $ip
Pinger = $pinger
Task = $pinger.SendPingAsync($ip, $TimeoutMs)
}
}
$alive = foreach ($job in $jobs) {
try {
$null = $job.Task.Wait($TimeoutMs + 500) # all tasks already run in parallel
$reply = $job.Task.Result
if ($reply.Status -eq [System.Net.NetworkInformation.IPStatus]::Success) {
[PSCustomObject]@{
IPAddress = $reply.Address.ToString()
TimeMs = $reply.RoundtripTime
}
}
} catch {
# host down / unreachable / timeout
} finally {
$job.Pinger.Dispose()
}
}
# ---------- Optional reverse DNS ----------
if ($ResolveHostname -and $alive) {
foreach ($host in $alive) {
try {
$host | Add-Member -NotePropertyName Hostname `
-NotePropertyValue ([System.Net.Dns]::GetHostEntry($host.IPAddress).HostName)
} catch {
$host | Add-Member -NotePropertyName Hostname -NotePropertyValue '(n/a)'
}
}
}
# ---------- Output ----------
if ($alive) {
Write-Host "`n$($alive.Count) host(s) responded:`n" -ForegroundColor Green
$alive | Sort-Object IPAddress | Format-Table -AutoSize
} else {
Write-Host "`nNo hosts responded." -ForegroundColor Yellow
}
Traceroute to a Given IP Address
tracert -d 8.8.8.8
Test-NetConnection 8.8.8.8 -TraceRoute
Connect via TCP to a Given Host/Port
There is no more telnet installed by default, so no way to do it natively in cmd.exe,
only PowerShell.
Test-NetConnection 8.8.8.8 -Port 443
Answer should tell whether the connection succeeded or not:
ComputerName : 8.8.8.8
RemoteAddress : 8.8.8.8
RemotePort : 443
InterfaceAlias : ProtonVPN
SourceAddress : 10.2.0.2
TcpTestSucceeded : True
Run TCP Port Scanner for a Host
cmd kind of version, as there is no telnet client we have to use PowerShell, but from CMD:
for /L %p in (20,1,25) do @powershell -Command "if ((New-Object Net.Sockets.TcpClient).ConnectAsync('192.168.3.13', %p).Wait(500)) { exit 0 } else { exit 1 }" && echo Port %p is OPEN
-
PowerShell (also async) version:
Here:
-
Scan ports 20 to 25 inclusive
-
Scan host 192.168.3.13
-
Use timeout of 500 msecs
-
Scanning is asynchronous, not waiting for a given port to answer, so is fast
20..25 | ForEach-Object {
$client = New-Object System.Net.Sockets.TcpClient
# Start an asynchronous connection attempt to the target port
$async = $client.BeginConnect("192.168.3.13", $_, $null, $null)
# Wait for 500 milliseconds for the connection to succeed
$wait = $async.AsyncWaitHandle.WaitOne(500, $false)
# If connected within the timeout, output the result and close the async hook
if ($wait -and $client.Connected) {
[PSCustomObject]@{
Port = $_
Status = "Open"
}
$client.EndConnect($async)
}
# Clean up the network resource
$client.Close()
}
Output:
Port Status ---- ------ 20 Open 21 Open 22 Open 25 Open
Download File via HTTP/HTTPS
|
Warning
|
certutil is not really meant for file downloads, so while it works, there is 99% chance Microsoft Defender will
block the download with notification on malware presence.
|
Here I explicitly allowed the download.
certutil -urlcache -split -f "https://yurisk.info/assets/OSPF-fail-scenario.svg" scenario.svg
*** Online ****
0000 ...
6b10
CertUtil: -URLCache command completed successfully.
Invoke-WebRequest -Uri "https://github.com/yuriskinfo/cheat-sheets/blob/master/cheat-sheets/fortigate-ssl-vpn-hardening-guide.pdf" -OutFile cheat-sheet.pdf
Show Routing Table of the Local Host
route print
Get-NetRoute
Resolve a Domain Name
nslookup google.com
Resolve-DnsName google.com
Resolve MX Record Specifying Custom DNS Server
nslookup -type=MX yurisk.info 1.1.1.1
Resolve-DnsName yurisk.info -Type MX -Server 1.1.1.1
Show DNS SOA Record for a Domain
nslookup -type=SOA yurisk.info
Resolve-DnsName yurisk.info -Type SOA
Show Local DNS Cached Resolved Names
ipconfig /displaydns
Get-DnsClientCache
Show Contents of hosts file
type %SYSTEMROOT%\System32\drivers\etc\hosts
Get-Content "$env:SystemRoot\System32\drivers\etc\hosts"
Show Windows Firewall Status for an Active Profile
netsh advfirewall show currentprofile
Get-NetConnectionProfile | ForEach-Object { Get-NetFirewallProfile -Name $_.NetworkCategory }
Disable Windows Firewall
|
Note
|
Must run as Administrator |
netsh advfirewall set allprofiles state off
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False
Enable Windows Firewall
netsh advfirewall set allprofiles state off
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled True
Show Incoming/Inbound Rules of the Windows Firewall
netsh advfirewall firewall show rule name=all dir=in
Get-NetFirewallRule -Direction Inbound | `
Where-Object Enabled -eq "True" | `
Select-Object DisplayName, Action, Direction
Show Interfaces and their Status
netsh interface show interface
Get-NetAdapter | Select-Object Name, InterfaceDescription, Status, LinkSpeed
Show Full Interface Parameters including MTU
ipconfig /all & netsh interface ipv4 show subinterfaces
Get-NetIPInterface | Select-Object InterfaceAlias, AddressFamily, NlMtu, ConnectionState, Dhcp
Show All Network Connections with Ports and IPs
netstat -ano
Get-NetTCPConnection | Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort, State
Show Only Ports in Listening State
netstat -ano | findstr /R /C:"LISTENING"
Get-NetTCPConnection -State Listen | `
Select-Object LocalAddress, LocalPort, OwningProcess
Show ARP table
arp -a
Get-NetNeighbor -AddressFamily IPv4
Show IPv6 Neighbors Table
netsh interface ipv6 show neighbors
Get-NetNeighbor -AddressFamily IPv6
List of Installed Patches and Hotfixes
|
Note
|
Requires Admin privileges to run |
wmic qfe get HotFixID,Description,InstalledOn
-or-
dism /online /get-packages /format:table
Get-HotFix
Show Running Services
sc query
Get-Service | Where-Object Status -eq 'Running'
Show Current User
whoami
[System.Security.Principal.WindowsIdentity]::GetCurrent().Name
Show Time Zone Set and Current Time
tzutil /g & echo %DATE% %TIME%
Get-TimeZone; Get-Date
Show Hosts Currently Visible and Active on local Host
Get-NetNeighbor | Where-Object State -in ("Reachable", "Permanent") | `
Select-Object IPAddress, LinkLayerAddress, State
Show Whether RDP is Enabled on Local Host
reg query "HKLM\System\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections
|
Note
|
0 means enabled, 1 means disabled. |
(Get-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server').fDenyTSConnections -eq 0
|
Note
|
True - enabled, False - disabled. |
Show on What Port RDP is Enabled
reg query "HKLM\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v PortNumber
|
Note
|
Answer is in hex, port 3389 will be 0xd3d. |
(Get-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp').PortNumber
Show Installed PowerShell Version
powershell -Command "$PSVersionTable.PSVersion"
$PSVersionTable.PSVersion
Related
I also write cheat sheets/scripts/guides to help in a daily work at Github at https://github.com/yuriskinfo and https://www.linkedin.com/in/yurislobodyanyuk/