Troubleshoot Networks with PowerShell

Run layered network diagnostics and build a reusable PowerShell script.

Introduction

30 Second Summary

When your internet is slow or a website refuses to load, the first thing most people do is restart the router. IT professionals follow a structured process to pinpoint exactly where the problem is, from the network adapter all the way to the remote server.

In this project, you will use PowerShell to run real network diagnostic commands against live targets, interpret their output, and combine key checks into a reusable troubleshooting script.

What You'll Build

A structured network troubleshooting workflow executed entirely in PowerShell, using built-in cmdlets to diagnose adapter configuration, DNS resolution, connectivity, routing, and active connections.

By the end of this project, you'll have:

  • A working mental model of the layered network troubleshooting workflow (adapter, DNS, connectivity, routing, connections).
  • Hands-on experience with every core PowerShell network diagnostic cmdlet and knowledge of when to use each one.
  • A reusable Network-Diagnostic.ps1 script that runs layered checks against any target.
  • Secret Mission: extend your diagnostic script to accept a target as a parameter and output results to a formatted HTML report.

Are there any prerequisites?

You need a Windows 10 or Windows 11 machine with PowerShell (built-in). Basic familiarity with running commands and piping output in PowerShell is helpful. No additional software installs are required.

Inspect Your Network Adapter and IP Configuration

Every network troubleshooting session starts at the bottom layer: your local machine's network hardware and configuration.

Before you can diagnose whether a remote server is reachable, you need to confirm your own machine is properly connected. In this step, you will inspect your network adapters, IP addresses, DNS servers, and default gateway using built-in PowerShell cmdlets.

In this step, get ready to:
  • View your network adapter names, statuses, and link speeds.
  • Check your IPv4 addresses and DNS server assignments.
  • Identify your default gateway and understand where traffic goes by default.
View your network adapters

A network adapter is the hardware (or virtual) interface that connects your machine to a network. You might have a Wi-Fi adapter, an Ethernet adapter, or both.

  • List all network adapters on your machine by running this command:
Get-NetAdapter

You should see a table with columns like Name, Status, and LinkSpeed. At least one adapter should show a status of Up.

  • Get a more detailed view of key properties by running this command:
Get-NetAdapter -Name * | Format-List -Property Name, Status, LinkSpeed, MacAddress

What does this command do?

The -Name * part selects all adapters. Piping to Format-List switches from table format to a vertical list, which is easier to read when you want to inspect specific properties per adapter.

The MacAddress is your adapter's unique hardware identifier. LinkSpeed tells you the connection speed (e.g., 1 Gbps for wired, or lower for Wi-Fi).

Don't see any adapters?

Make sure you are running PowerShell as an Administrator. Some adapter information requires elevated permissions. Right-click the PowerShell icon and select Run as administrator.

Help me troubleshoot why Get-NetAdapter returns no results

Check your IP addresses and DNS server configuration

Now that you know which adapters are active, you need to confirm they have valid IP addresses and that DNS servers are properly assigned.

  • View your IPv4 addresses by running this command:
Get-NetIPAddress -AddressFamily IPv4 | Format-Table InterfaceAlias, IPAddress, PrefixLength

You should see a table showing each interface's name, its IP address, and the prefix length (subnet mask size). Look for your main adapter's IP. It is typically something like 192.168.x.x or 10.x.x.x on a home network.

What is PrefixLength?

PrefixLength is the number of bits in the subnet mask. A value of 24 means the first 24 bits define your network (equivalent to a subnet mask of 255.255.255.0). Devices sharing the same prefix are on the same local subnet.

  • Confirm which DNS servers each interface is using by running this command:
Get-DnsClientServerAddress -AddressFamily IPv4 | Format-Table InterfaceAlias, ServerAddresses

You should see your active interface listed with one or more DNS server IP addresses. Common values include your router's IP (like 192.168.1.1) or public DNS servers like 8.8.8.8.

Why does the DNS server matter?

Your DNS server is responsible for translating domain names (like google.com) into IP addresses your machine can reach. If DNS is misconfigured or unreachable, websites will fail to load even though your network connection is otherwise healthy.

Seeing empty ServerAddresses?

If an interface shows empty DNS server addresses, it is likely a virtual adapter (like a VPN or Hyper-V switch) that is not actively used for internet traffic. Look for results on your primary Wi-Fi or Ethernet interface instead.

Help me understand my DNS server output

Verify your default gateway

The default gateway is the router that handles all traffic when your machine does not have a more specific route. If your default gateway is missing or incorrect, you cannot reach anything outside your local subnet.

  • View your default gateway by running this command:
Get-NetRoute -DestinationPrefix "0.0.0.0/0" | Select-Object InterfaceAlias, NextHop, RouteMetric

You should see at least one row. The NextHop column shows your gateway's IP address (commonly your router, like 192.168.1.1).

What does 0.0.0.0/0 mean?

The destination 0.0.0.0/0 means "all addresses." This is the catch-all route. When your machine wants to reach an IP that does not match a more specific route in the table, it sends the traffic to this NextHop (your gateway).

The RouteMetric is a priority value. Lower numbers mean higher priority. If you have multiple default routes (e.g., Wi-Fi and Ethernet), Windows uses the one with the lowest metric.

No results returned?

If no default route appears, your machine has no gateway configured. This means you can only communicate with devices on your local subnet. Check that your network adapter has a valid connection and that DHCP assigned a gateway, or that you set one manually.

Help me troubleshoot a missing default gateway

You now have a clear picture of your machine's network foundation: which adapters are active, what IP addresses they hold, which DNS servers they query, and where default traffic goes. Next up, you will put that DNS configuration to the test by resolving domain names and diagnosing lookup issues.

Troubleshoot DNS Resolution

You now know what your network adapters look like, which IP addresses are assigned, and where your default gateway points.

The next layer to investigate is DNS resolution. When you type a domain name like google.com, your computer needs to translate that into an IP address before it can connect.

If DNS fails, everything looks broken even though your network connection is perfectly fine. In this step, you will use PowerShell to resolve domain names, query specific DNS servers, and manage your local DNS cache.

In this step, get ready to:
  • Resolve domain names and query specific DNS record types.
  • Query a specific DNS server and measure how long resolution takes.
  • Inspect and flush your local DNS cache.
Resolve a domain name and query specific record types

The Resolve-DnsName cmdlet is PowerShell's replacement for the older nslookup tool. It lets you look up domain names, query specific record types, and control which DNS protocol to use.

  • Perform a basic DNS lookup by running this command:
Resolve-DnsName -Name google.com

You should see one or more IP addresses returned alongside the record type (A or AAAA) and the TTL (time to live) value.

  • Query the mail exchange (MX) records for the same domain by running:
Resolve-DnsName -Name google.com -Type MX

You should see mail server hostnames and their priority values. MX records tell other mail servers where to deliver email for a domain.

  • Force a DNS-only resolution (skipping LLMNR and NetBIOS) by running:
Resolve-DnsName -Name google.com -Type A -DnsOnly

What does -DnsOnly do?

By default, Windows tries multiple name resolution methods: DNS, LLMNR (Link-Local Multicast Name Resolution), and NetBIOS. The -DnsOnly flag restricts the query to the DNS protocol only.

This is useful when troubleshooting because it isolates DNS behavior from other name resolution fallbacks that could mask the real problem.

Seeing a DNS name does not exist error?

Make sure you typed the domain name correctly. A typo like gogle.com will fail to resolve.

If a valid domain still fails, your configured DNS server may be unreachable. You confirmed your DNS servers in Step 1. Try pinging one of them to check connectivity.

Help me troubleshoot why Resolve-DnsName is returning an error for a valid domain.

Query a specific DNS server and measure resolution time

Sometimes the DNS server your system is configured to use is slow or returning stale results. You can point Resolve-DnsName at a different DNS server to compare behavior.

  • Query Google's public DNS server directly by running:
Resolve-DnsName -Name google.com -Server 8.8.8.8

You should see the same IP addresses as before, but this time the query went to 8.8.8.8 instead of your default DNS server.

When would I use -Server?

If your default DNS server is returning errors or stale data, querying a public DNS server like 8.8.8.8 (Google) or 1.1.1.1 (Cloudflare) helps you determine whether the problem is with your DNS server specifically or with the domain itself.

  • Measure how long DNS resolution takes by running:
(Measure-Command {Resolve-DnsName -Name google.com -Server 8.8.8.8 -DnsOnly}).TotalMilliseconds

You should see a number representing milliseconds. A result under 100ms is excellent. Under 1000ms is acceptable. Anything above that suggests a slow or overloaded DNS server.

What does Measure-Command do?

Measure-Command wraps any PowerShell command and times how long it takes to execute. The .TotalMilliseconds property extracts just the time value in milliseconds from the result.

Getting a very high number or timeout?

If resolution takes more than 5000ms, the DNS server at 8.8.8.8 may be blocked by your network (some corporate firewalls block external DNS). Try replacing 8.8.8.8 with your default DNS server address from Step 1.

Help me figure out why DNS resolution is timing out when querying 8.8.8.8.

Inspect and flush the DNS cache

Windows maintains a local DNS cache so it does not have to query a DNS server for every single request. Stale cache entries can cause you to connect to old IP addresses even after a domain has moved to a new server.

  • View the first 10 entries in your DNS cache by running:
Get-DnsClientCache | Select-Object -First 10 Entry, RecordName, Data

You should see a table with cached domain names and their resolved IP addresses. The entries you see include domains your system has recently resolved, including the google.com queries you just ran.

  • Flush the entire DNS cache by running:
Clear-DnsClientCache

What does Clear-DnsClientCache do?

This is the PowerShell equivalent of running ipconfig /flushdns in Command Prompt. It removes all cached DNS entries, forcing your system to perform fresh lookups on the next request.

Flushing the cache is one of the first things to try when a website is unreachable but other sites work fine.

  • Confirm the cache is now empty by running the same query again:
Get-DnsClientCache | Select-Object -First 10 Entry, RecordName, Data

You should see no output, or a very small number of entries that were cached in the brief moment since you flushed.

Still seeing cached entries after flushing?

If you ran the second Get-DnsClientCache command immediately, Windows may have already re-cached a few entries from background processes. This is normal. The key indicator is that the cache is significantly smaller than before you flushed.

If the Clear-DnsClientCache command itself throws an access denied error, you may need to run PowerShell as Administrator. Right-click the PowerShell icon and select Run as administrator.

Help me troubleshoot why Clear-DnsClientCache is not working.

You can now resolve domain names, compare DNS servers, and clear stale cache entries. Next up, you will test whether you can actually reach remote hosts using ICMP ping and TCP port checks.

Test Connectivity with Ping and TCP

You can now resolve domain names and confirm your DNS configuration is healthy. The next question is: can your machine actually reach those resolved addresses?

In this step, you will test raw network connectivity using two different approaches. First, you will send ICMP echo requests (ping) to confirm a host is reachable. Then you will test specific TCP ports to confirm that services on that host are accepting connections.

In this step, get ready to:
  • Send ICMP ping requests and observe latency values.
  • Test TCP port connectivity to confirm specific services are reachable.
  • Use shorthand parameters for quick service checks.
Ping a remote host with Test-Connection

A ping sends a small packet to a remote host and waits for a reply. If a reply comes back, you know the host is reachable and you can measure the round-trip latency.

  • Send 4 ICMP echo requests to Google's public DNS server by running this command:
Test-Connection -TargetName 8.8.8.8 -Count 4

What does this command do?

Test-Connection sends ICMP echo requests, the same protocol behind the classic ping command.

  • -TargetName 8.8.8.8 specifies the IP address to ping.
  • -Count 4 limits the requests to 4 packets instead of running continuously.

You should see 4 replies with latency values in milliseconds. A latency under 50ms to 8.8.8.8 is typical for most connections.

Using Windows PowerShell 5.1?

If you see an error about -TargetName not being recognized, you are running Windows PowerShell 5.1. In that version, the parameter is called -ComputerName instead.

Replace -TargetName with -ComputerName for all Test-Connection commands throughout this project. All other cmdlets work the same in both versions.

For scripting scenarios, you often just need a yes-or-no answer: is the host reachable or not?

  • Run the same ping with the -Quiet flag to get a simple True/False result:
Test-Connection -TargetName 8.8.8.8 -Count 4 -Quiet

When would I use -Quiet?

The -Quiet flag returns True if at least one ping succeeds, or False if all fail. This is perfect for scripts where you want to check reachability inside an if statement.

You should see True in the output, confirming that 8.8.8.8 is reachable from your machine.

Getting False or request timed out?

Some corporate networks or firewalls block ICMP traffic. If you are on a VPN or corporate network, try disconnecting and retesting.

Also check that your Wi-Fi or Ethernet adapter shows Up status from Step 1. A disconnected adapter cannot send any traffic.

Help me troubleshoot why my ping to 8.8.8.8 is failing in PowerShell.

Test TCP port connectivity with Test-NetConnection

Ping tells you a host is reachable, but it does not tell you if a specific service is running. A web server might respond to ping but have its HTTPS port blocked.

Test-NetConnection goes further by testing whether a specific TCP port is open and accepting connections.

  • Test HTTPS connectivity to Google by running this command:
Test-NetConnection -ComputerName google.com -Port 443 -InformationLevel Detailed

What does this command do?

  • -ComputerName google.com is the target host to test.
  • -Port 443 tests the HTTPS port specifically.
  • -InformationLevel Detailed shows extra fields like DNS resolution results and interface information.

Look for these key fields in the output:

  • TcpTestSucceeded should show True, meaning port 443 is open.
  • RemoteAddress shows the resolved IP address of google.com.
  • NameResolutionResults shows the DNS resolution that happened as part of the connection test.

Now compare what happens when you test different ports.

  • Test HTTP (port 80) by running:
Test-NetConnection -ComputerName google.com -Port 80
  • Test SSH (port 22) by running:
Test-NetConnection -ComputerName google.com -Port 22

What should I see?

Port 80 (HTTP) should show TcpTestSucceeded: True because Google accepts HTTP connections.

Port 22 (SSH) should show TcpTestSucceeded: False because Google does not run a public SSH service. This is how you distinguish between a reachable host and an available service.

All ports showing False?

If even port 443 returns False, your network may be filtering outbound TCP connections. This is common on restrictive corporate or school networks.

Try testing against a different target like microsoft.com on port 443. If that also fails, your firewall is likely blocking outbound HTTPS.

Help me figure out why Test-NetConnection shows TcpTestSucceeded as False for port 443.

Use CommonTCPPort for quick service checks

Remembering port numbers is not always convenient. PowerShell offers a shorthand parameter that lets you test common services by name instead of number.

  • Run a quick HTTP service check using the -CommonTCPPort parameter:
Test-NetConnection -ComputerName google.com -CommonTCPPort HTTP

What values does -CommonTCPPort accept?

The -CommonTCPPort parameter accepts four shorthand values:

  • HTTP (port 80).
  • RDP (port 3389, Remote Desktop).
  • SMB (port 445, file sharing).
  • WINRM (port 5985, Windows Remote Management).

For any port not in this list, use the -Port parameter with the numeric value instead.

You should see TcpTestSucceeded: True in the output, confirming that Google is accepting HTTP connections on port 80.

You can now confirm whether a host is reachable and whether specific services on that host are accepting connections. Next up, you will trace the actual path your traffic takes to reach a remote host and inspect your routing table.

Diagnose Routing and Trace the Path

You now know your network can resolve names and reach remote hosts. But what happens when traffic takes an unexpected path or gets dropped along the way?

Routing determines which path your packets take to reach a destination. Every Windows machine maintains a routing table that maps destination networks to the correct gateway. In this step, you will inspect that table, trace the actual hops your traffic takes, and let Windows diagnose which route it selects for a given target.

In this step, get ready to:
  • View your full IPv4 routing table and identify key routes.
  • Trace the route your traffic takes to a remote host.
  • Run route diagnostics to understand multi-interface routing decisions.
View your routing table

Your machine's routing table is a set of rules that tells Windows where to send packets based on their destination address. Every packet that leaves your machine is matched against this table to find the best route.

  • View all IPv4 routes sorted by metric by running this command:
Get-NetRoute -AddressFamily IPv4 | Sort-Object -Property RouteMetric | Format-Table DestinationPrefix, NextHop, RouteMetric, InterfaceAlias

What does this output tell you?

Each row is a route rule. Here is what to look for:

  • DestinationPrefix is the network range the rule applies to. 0.0.0.0/0 is the default route, which catches all traffic that does not match a more specific rule.
  • NextHop is the gateway address where traffic is forwarded. A NextHop of 0.0.0.0 means the destination is directly connected (no forwarding needed).
  • RouteMetric is the priority. Lower numbers are preferred when multiple routes match the same destination.

You should see a table with multiple routes. Look for your default route (0.0.0.0/0) with a NextHop that matches your router's IP address, plus local subnet routes for your connected networks.

Not seeing a default route?

  • If no 0.0.0.0/0 row appears, your adapter may not have a gateway configured. Run Get-NetIPConfiguration to check whether a default gateway is assigned.
  • If you see multiple default routes with the same metric, Windows will use the first one it finds. This can happen with both Wi-Fi and Ethernet connected simultaneously.

Still confused about your routing table?

Trace the route to a remote host

The routing table shows you the rules, but a trace route shows you the actual path. Each hop in the trace is a router between you and the destination.

  • Trace the path your traffic takes to reach google.com by running this command:
Test-NetConnection -ComputerName google.com -TraceRoute

What does this output tell you?

The output includes a TraceRoute property listing IP addresses of each router your packet passed through. The first hop is usually your local gateway. Subsequent hops are your ISP's routers and intermediate networks.

High latency at a specific hop can indicate where a bottleneck or problem is occurring. If a hop shows a timeout (asterisk or no response), that router may be configured to block ICMP packets, which is not necessarily a failure.

You should see a list of IP addresses representing each hop between your machine and google.com. The number of hops varies based on your network location, but typically ranges from 5 to 20.

Seeing all timeouts or no hops?

  • Some corporate firewalls block outbound ICMP, which prevents trace route from working. Try a different target like 8.8.8.8 to rule out DNS issues.
  • If you are on a VPN, the trace route may show only a few hops because the VPN tunnel hides intermediate routers.

Help me understand why my trace route is not showing any hops.

Run route diagnostics

When your machine has multiple network interfaces (Wi-Fi, Ethernet, VPN), Windows has to decide which one to use for each destination. Route diagnostics reveal that decision.

  • Run route diagnostics against google.com by running this command:
Test-NetConnection -ComputerName google.com -DiagnoseRouting -InformationLevel Detailed

What does this output tell you?

The -DiagnoseRouting flag tells Windows to show which route and source address it selected to reach the target. This is especially useful in multi-NIC environments where traffic might go out the wrong interface.

  • SelectedSourceAddress shows which of your local IP addresses Windows chose to send from.
  • SelectedNetRoute shows which routing table entry matched the destination.
  • OutgoingInterfaceIndex identifies which network adapter the traffic uses.

You should see routing diagnostic details including the selected source address and the route Windows chose. The interface alias should match your active network adapter from Step 1.

Seeing RouteDiagnosticsSucceeded: False?

  • This means Windows could not find a valid route to the destination. Check that your default gateway is reachable by running Test-Connection -TargetName followed by your gateway IP from Step 1.
  • If you are connected via VPN, the VPN client may override your routing table. Try disconnecting the VPN and running the command again.

Help me understand why route diagnostics are failing.

You now understand how Windows routes traffic and can trace the exact path packets take. Next up, you will inspect the active TCP connections on your machine to see what is already communicating and which processes own those connections.

Inspect Active TCP Connections

You've confirmed your machine can reach remote hosts and traced the path packets take to get there.

Now it's time to look inward. Your computer maintains dozens (sometimes hundreds) of active TCP connections at any given moment. Every open browser tab, background sync, and cloud app keeps a connection alive. In this step, you'll inspect those connections and identify exactly which process is responsible for each one.

In this step, get ready to:
  • View all established TCP connections sorted by remote port.
  • Filter connections by port number and connection state.
  • Map each connection to the process that owns it.
View all established connections

The Get-NetTCPConnection cmdlet shows every TCP connection your machine currently holds. Filtering by state lets you focus on the connections that are actively exchanging data.

  • View all established TCP connections sorted by remote port by running this command:
Get-NetTCPConnection -State Established | Sort-Object -Property RemotePort | Format-Table LocalAddress, LocalPort, RemoteAddress, RemotePort, OwningProcess

What does this command do?

-State Established filters to only connections that are actively open and exchanging data. This excludes connections in states like Listen, TimeWait, or CloseWait.

The OwningProcess column shows the process ID (PID) that owns each connection. You'll use this in the next substep to map connections to actual application names.

You should see a table with your active connections. Common entries include connections to port 443 (HTTPS) from your browser, or port 53 (DNS) from system processes.

Seeing an empty table?

If no results appear, you may not have any active connections at the moment. Open a browser tab and navigate to any website, then re-run the command.

Help me troubleshoot why Get-NetTCPConnection shows no established connections.

Find connections by port or remote address

When troubleshooting a specific service, you don't want to scroll through every connection. Filtering by port or state narrows the view to exactly what matters.

  • Filter to only HTTPS connections by running this command:
Get-NetTCPConnection -RemotePort 443

What does this show?

Port 443 is the standard port for HTTPS traffic. Every secure website your browser connects to uses this port. This filter is useful when you want to see which encrypted connections your machine is maintaining.

  • Now see which ports your machine is actively listening on by running this command:
Get-NetTCPConnection -State Listen | Format-Table LocalAddress, LocalPort, OwningProcess

What's the difference between Established and Listen?

Established means two machines are actively exchanging data. Listen means your machine has a port open and is waiting for incoming connections. Services like web servers, databases, and RDP all show up in the Listen state.

You should see a list of local ports your machine is listening on. The OwningProcess column shows which process ID opened each port.

Getting a parameter error?

Make sure you're typing -RemotePort (not -Port). The Get-NetTCPConnection cmdlet uses -RemotePort and -LocalPort to distinguish direction.

Help me fix my Get-NetTCPConnection filtering command.

Identify the process behind a connection

Knowing a connection exists is useful, but knowing which application created it is where real troubleshooting happens. This is the PowerShell equivalent of asking "what's using this port?"

  • View established connections with their process names by running this command:
Get-NetTCPConnection -State Established | Select-Object RemoteAddress, RemotePort, OwningProcess, @{Name="ProcessName";Expression={(Get-Process -Id $_.OwningProcess).ProcessName}} | Format-Table

What does this command do?

The @{Name="ProcessName";Expression={...}} syntax creates a calculated property. For each connection, it takes the OwningProcess ID and passes it to Get-Process to look up the actual application name.

This turns a raw number like 12384 into a recognizable name like chrome or msedge. Now you can instantly tell which app is talking to which remote server.

You should see a table where each row shows a remote address, port, process ID, and the process name that owns that connection.

Seeing blank ProcessName values?

Some system-level connections are owned by processes that require elevated permissions to identify. Try running PowerShell as Administrator (right-click the PowerShell icon and select **Run as administrator**).

Also, a connection may close between the time Get-NetTCPConnection runs and when Get-Process looks up the PID. This is normal for short-lived connections.

Help me understand why some process names are blank in my connection list.

You now have full visibility into what your machine is doing on the network. You can see every active connection, filter by port or state, and trace each one back to the responsible application. Next up, you'll combine all the diagnostic commands from this project into a single reusable script.

Build Your Diagnostic Script

You've now run every major PowerShell network diagnostic cmdlet individually. You know how to check adapters, resolve DNS, test connectivity, trace routes, and inspect connections.

In this step, you'll combine all of those commands into a single reusable script. Instead of typing each command from memory, you'll have a one-click diagnostic tool that runs a full layered network health check against any target.

In this step, get ready to:
  • Create a PowerShell script file that organizes your diagnostic output.
  • Add layered diagnostic commands covering adapters, DNS, connectivity, routing, and connections.
  • Run the script and verify all sections produce output.
Create the script file

A .ps1 file is a PowerShell script that you can run anytime with a single command. You'll create one on your Desktop so it's easy to find.

  • Move to your Desktop by running this command:
cd ~/Desktop
  • Create the script file and open it in Notepad by running these commands:
New-Item -Name "Network-Diagnostic.ps1" -ItemType File
notepad Network-Diagnostic.ps1

What does this do?

New-Item creates an empty file called Network-Diagnostic.ps1 on your Desktop. The second command opens it in Notepad so you can start writing your script.

  • Confirm the file exists by running:
ls Network-Diagnostic.ps1

You should see Network-Diagnostic.ps1 listed in the output.

Every diagnostic script needs a clear target and a readable header. This makes the output easy to interpret when you run it later.

  • In Notepad, paste the following code into your empty Network-Diagnostic.ps1 file:
# Define the target host for all diagnostic checks
$Target = "google.com"

# Print a formatted report header with the target and timestamp
Write-Host "===================================" -ForegroundColor Cyan
Write-Host " Network Diagnostic Report" -ForegroundColor Cyan
Write-Host " Target: $Target" -ForegroundColor Cyan
Write-Host " Date: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" -ForegroundColor Cyan
Write-Host "===================================" -ForegroundColor Cyan
Write-Host ""

What does this code do?

  • $Target stores the hostname that every diagnostic command will check. You only need to change this one variable to test a different host.
  • The Write-Host lines create a colored banner so you can quickly identify what the report is testing and when it ran.
  • Get-Date -Format 'yyyy-MM-dd HH:mm:ss' stamps the report with the exact time you ran it.
  • Save the file in Notepad with Ctrl+S.
Add the diagnostic commands

Now you'll add the core commands from each previous step. Each section starts with a yellow header line so you can scan the output and jump to the section you need.

  • In Notepad, paste the following code below the header block you just added. These are sections 1 through 4, covering adapter info, IP addresses, DNS servers, and DNS resolution:
# Section 1: Network Adapter Info
Write-Host "--- Network Adapters ---" -ForegroundColor Yellow
Get-NetAdapter | Where-Object { $_.Status -eq "Up" } | Format-Table Name, Status, LinkSpeed, MacAddress -AutoSize

# Section 2: IP Configuration
Write-Host "--- IPv4 Addresses ---" -ForegroundColor Yellow
Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.IPAddress -ne "127.0.0.1" } | Format-Table InterfaceAlias, IPAddress, PrefixLength -AutoSize

# Section 3: DNS Server Configuration
Write-Host "--- DNS Servers ---" -ForegroundColor Yellow
Get-DnsClientServerAddress -AddressFamily IPv4 | Where-Object { $_.ServerAddresses.Count -gt 0 } | Format-Table InterfaceAlias, ServerAddresses -AutoSize

# Section 4: DNS Resolution Test
Write-Host "--- DNS Resolution: $Target ---" -ForegroundColor Yellow
Resolve-DnsName -Name $Target -Type A -DnsOnly -ErrorAction SilentlyContinue | Format-Table Name, Type, TTL, IPAddress -AutoSize

What does this code do?

  • Section 1 filters adapters to only show ones with Status "Up", so you don't see disconnected or virtual adapters cluttering your report.
  • Section 2 excludes the loopback address (127.0.0.1) since it's always present and not useful for diagnostics.
  • Section 3 filters to interfaces that actually have DNS servers configured, skipping empty entries.
  • -ErrorAction SilentlyContinue in Section 4 prevents the script from stopping if DNS resolution fails. A failed lookup is useful diagnostic information, not a reason to crash.
  • Now paste the following code below Section 4. These are sections 5 through 8, covering ping, TCP port testing, routing, and active connections:
# Section 5: Ping Test
Write-Host "--- Ping Test: $Target ---" -ForegroundColor Yellow
Test-Connection -TargetName $Target -Count 4 | Format-Table Destination, Latency, Status -AutoSize

# Section 6: TCP Port Test (HTTPS)
Write-Host "--- TCP Port 443 Test: $Target ---" -ForegroundColor Yellow
$tcpResult = Test-NetConnection -ComputerName $Target -Port 443
Write-Host "  Remote Address: $($tcpResult.RemoteAddress)"
Write-Host "  TCP Test Succeeded: $($tcpResult.TcpTestSucceeded)"
Write-Host ""

# Section 7: Route to Target
Write-Host "--- Trace Route: $Target ---" -ForegroundColor Yellow
Test-NetConnection -ComputerName $Target -TraceRoute | Select-Object -ExpandProperty TraceRoute

Write-Host ""
Write-Host "--- Default Gateway ---" -ForegroundColor Yellow
Get-NetRoute -DestinationPrefix "0.0.0.0/0" | Format-Table InterfaceAlias, NextHop, RouteMetric -AutoSize

# Section 8: Active Connections Summary
Write-Host "--- Established Connections (Top 10 by Remote Port) ---" -ForegroundColor Yellow
Get-NetTCPConnection -State Established |
    Sort-Object -Property RemotePort |
    Select-Object -First 10 LocalAddress, LocalPort, RemoteAddress, RemotePort, @{Name="ProcessName";Expression={(Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue).ProcessName}} |
    Format-Table -AutoSize

Write-Host "===================================" -ForegroundColor Cyan
Write-Host " Diagnostic Complete" -ForegroundColor Cyan
Write-Host "===================================" -ForegroundColor Cyan

What does this code do?

  • Section 5 sends 4 ICMP pings and formats the latency results as a table.
  • Section 6 stores the TCP test result in $tcpResult so you can print individual properties (RemoteAddress and TcpTestSucceeded) cleanly.
  • Section 7 traces the route to the target and also shows your default gateway for reference.
  • Section 8 uses a calculated property to look up the process name for each connection, so you can see which application owns each connection.

Using PowerShell 5.1?

The script uses -TargetName for Test-Connection, which is the PowerShell 7+ syntax. If you're using Windows PowerShell 5.1 (the built-in version), replace -TargetName with -ComputerName in Section 5. You can check your version by running $PSVersionTable.PSVersion.

  • Save the file in Notepad with Ctrl+S.

✔️ Awesome, I've got everything!

Great. Double check you've saved your file before moving on.

ⓧ I'd like to double check the full code

Here's the complete Network-Diagnostic.ps1 file. Make sure your code matches this exactly:

$Target = "google.com"

Write-Host "===================================" -ForegroundColor Cyan
Write-Host " Network Diagnostic Report" -ForegroundColor Cyan
Write-Host " Target: $Target" -ForegroundColor Cyan
Write-Host " Date: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" -ForegroundColor Cyan
Write-Host "===================================" -ForegroundColor Cyan
Write-Host ""

# Section 1: Network Adapter Info
Write-Host "--- Network Adapters ---" -ForegroundColor Yellow
Get-NetAdapter | Where-Object { $_.Status -eq "Up" } | Format-Table Name, Status, LinkSpeed, MacAddress -AutoSize

# Section 2: IP Configuration
Write-Host "--- IPv4 Addresses ---" -ForegroundColor Yellow
Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.IPAddress -ne "127.0.0.1" } | Format-Table InterfaceAlias, IPAddress, PrefixLength -AutoSize

# Section 3: DNS Server Configuration
Write-Host "--- DNS Servers ---" -ForegroundColor Yellow
Get-DnsClientServerAddress -AddressFamily IPv4 | Where-Object { $_.ServerAddresses.Count -gt 0 } | Format-Table InterfaceAlias, ServerAddresses -AutoSize

# Section 4: DNS Resolution Test
Write-Host "--- DNS Resolution: $Target ---" -ForegroundColor Yellow
Resolve-DnsName -Name $Target -Type A -DnsOnly -ErrorAction SilentlyContinue | Format-Table Name, Type, TTL, IPAddress -AutoSize

# Section 5: Ping Test
Write-Host "--- Ping Test: $Target ---" -ForegroundColor Yellow
Test-Connection -TargetName $Target -Count 4 | Format-Table Destination, Latency, Status -AutoSize

# Section 6: TCP Port Test (HTTPS)
Write-Host "--- TCP Port 443 Test: $Target ---" -ForegroundColor Yellow
$tcpResult = Test-NetConnection -ComputerName $Target -Port 443
Write-Host "  Remote Address: $($tcpResult.RemoteAddress)"
Write-Host "  TCP Test Succeeded: $($tcpResult.TcpTestSucceeded)"
Write-Host ""

# Section 7: Route to Target
Write-Host "--- Trace Route: $Target ---" -ForegroundColor Yellow
Test-NetConnection -ComputerName $Target -TraceRoute | Select-Object -ExpandProperty TraceRoute

Write-Host ""
Write-Host "--- Default Gateway ---" -ForegroundColor Yellow
Get-NetRoute -DestinationPrefix "0.0.0.0/0" | Format-Table InterfaceAlias, NextHop, RouteMetric -AutoSize

# Section 8: Active Connections Summary
Write-Host "--- Established Connections (Top 10 by Remote Port) ---" -ForegroundColor Yellow
Get-NetTCPConnection -State Established |
    Sort-Object -Property RemotePort |
    Select-Object -First 10 LocalAddress, LocalPort, RemoteAddress, RemotePort, @{Name="ProcessName";Expression={(Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue).ProcessName}} |
    Format-Table -AutoSize

Write-Host "===================================" -ForegroundColor Cyan
Write-Host " Diagnostic Complete" -ForegroundColor Cyan
Write-Host "===================================" -ForegroundColor Cyan
Run and verify the script

Your script is complete. Time to run it and confirm that every section produces output.

  • Back in your PowerShell window, make sure you're still in the Desktop directory. Run the script with this command:
.\Network-Diagnostic.ps1

You should see a cyan header banner followed by 8 yellow-titled sections, each with formatted output. The script ends with a cyan "Diagnostic Complete" footer.

What should I see?

The output scrolls through each section in order. You'll see your active network adapters, your IPv4 addresses, DNS servers, a DNS resolution result for google.com, ping latency values, a TCP port 443 test result, trace route hops, your default gateway, and your top 10 established connections with process names.

Some sections may take a few seconds (especially the trace route). The entire script should complete within 30-60 seconds.

Seeing an error when you run the script?

  • If you see "cannot be loaded because running scripts is disabled on this system", you need to allow script execution. Run Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned and then try again.
  • If you see "cannot find path", make sure you're in the same directory as the script. Run cd ~/Desktop first.
  • If Section 5 (Ping Test) fails with a parameter error, you may be on Windows PowerShell 5.1. Replace -TargetName with -ComputerName in Section 5, save, and try again.

Still stuck? Help me debug my Network-Diagnostic.ps1 script.

Secret mission

HTML Report Output

Your diagnostic script prints results to the console. That's useful for quick checks, but what if you need to share results with a colleague or save them for comparison? In this extension, you'll make the script accept any target as a parameter and generate a styled HTML report file.

Clean Up Your Resources

Clean Up Your Resources

This project runs entirely locally using built-in PowerShell modules, so there are no ongoing costs. Decide whether to keep your script file for future use, or remove it from your system.

Resources you used:

  • Network-Diagnostic.ps1 script file on your Desktop.
  • Built-in PowerShell modules (NetTCPIP, NetAdapter, DnsClient). These are part of Windows and do not need cleanup.

Keep everything running

No action needed. Choose this if you plan to keep using or extending your diagnostic script.

  • Your Network-Diagnostic.ps1 file stays on your Desktop, ready to run anytime.
  • No background processes or services were started by this project.

Pause - I'll come back to this later

Since this project uses only a local script file and built-in modules, there is nothing to pause. Your script file takes up minimal disk space and has no running processes.

  • Leave Network-Diagnostic.ps1 where it is. It uses negligible storage.
  • When you come back, open PowerShell, navigate to the script location, and run .\Network-Diagnostic.ps1 to pick up where you left off.

Delete - I don't want to use this again

Remove the script file from your system. The built-in PowerShell modules cannot and should not be removed.

  • Delete the Network-Diagnostic.ps1 file from your Desktop.
  • If you completed the Secret Mission, also delete any generated HTML report files (e.g., NetworkReport_*.html).
  • No accounts, cloud resources, or installed software need to be removed.

Nice Work!

Nice Work!

Congratulations! You now have hands-on experience with the core PowerShell network troubleshooting toolkit.

You've learned how to:

  • Diagnosed DNS, connectivity, and routing issues using PowerShell cmdlets like Resolve-DnsName, Test-Connection, and Test-NetConnection.
  • Inspected active TCP connections and identified which processes own them with Get-NetTCPConnection.
  • Built a reusable Network-Diagnostic.ps1 script that runs layered network checks against any target.
  • Secret Mission: Extended the diagnostic script with parameterized input and HTML report output.

Ready to quiz yourself?