Introduction

Troubleshooting network issues can be tedious and time-consuming. PowerShell can automate the process, monitoring network interfaces and connectivity by pinging a reliable server like Google’s DNS (8.8.8.8). This blog explores a practical solution to automate network diagnostics, saving time and ensuring reliability for IT professionals and home users.

Understanding the problem

Maintaining a reliable internet connection involves multiple components working together: network adapters, IP configurations, DNS settings, and physical connections. Some common problems include:

  • Misconfigured or disabled network adapters.
  • Connection lost due to hardware or cable issues.
  • DNS problems preventing access to external servers despite local connectivity.
  • Virtual or secondary adapters lacking proper configuration, leading to misleading status indicators.

This is where PowerShell script comes in, offering a straightforward and efficient way to handle these challenges. Let’s dive into how it works!

Step-by-Step Breakdown

This PowerShell script is designed to monitor and diagnose network connectivity by evaluating the IPv4 status of network interfaces and internet access. More specifically:

  • It works by enumerating all network adapters, identifying their connection profiles, and checking their IPv4 connectivity status.
  • To verify internet access, it repeatedly pings Google’s public DNS server (8.8.8.8) until an active connection is confirmed.

Retrieving Hardware and Binding Information

Before checking IPv4 connectivity, we need to gather detailed hardware and binding information for each network adapter. This helps in identifying specific issues related to hardware settings or binding configurations.

Using Get-NetAdapterHardwareInfo to get details about each adapter like interface type, speed, and vendor information. This command is useful for identifying hardware-related issues like unsupported speeds or mismatched configurations:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$HardwareInfo = Get-NetAdapterHardwareInfo
Write-Host "Hardware Information for Network Adapters:"
$HardwareInfo | Format-Table -AutoSize
$HardwareInfo = Get-NetAdapterHardwareInfo Write-Host "Hardware Information for Network Adapters:" $HardwareInfo | Format-Table -AutoSize
$HardwareInfo = Get-NetAdapterHardwareInfo

Write-Host "Hardware Information for Network Adapters:"
$HardwareInfo | Format-Table -AutoSize

Using Get-NetAdapterBinding to list the protocol bindings for each network adapter, such as IPv4, IPv6, helping ensure proper configurations. For instance:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$BindingInfo = Get-NetAdapterBinding
Write-Host "Binding Information for Network Adapters:"
$BindingInfo | Format-Table -AutoSize
$BindingInfo = Get-NetAdapterBinding Write-Host "Binding Information for Network Adapters:" $BindingInfo | Format-Table -AutoSize
$BindingInfo = Get-NetAdapterBinding

Write-Host "Binding Information for Network Adapters:"
$BindingInfo | Format-Table -AutoSize

Enumerating Network Interfaces

Next, you can start listing all network adapters using Get-NetAdapter command. Then extracting the names.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$NICNames = Get-NetAdapter | Select-Object -ExpandProperty Name
$NICNames = Get-NetAdapter | Select-Object -ExpandProperty Name
$NICNames = Get-NetAdapter | Select-Object -ExpandProperty Name
  • This retrieves the names of all available network interfaces (NICs).
  • The variable hold those names for further processing.

Checking IPv4 Connectivity

Using Get-netConnectionProfile to retrieve the IPv4 status for the NIC. The possible values are:

  • NoTraffic: No traffic is detected.
  • Internet: Full internet access is available.
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$Status = Get-NetConnectionProfile -InterfaceAlias $NICNames | Select-Object -ExpandProperty IPv4Connectivity
$Status = Get-NetConnectionProfile -InterfaceAlias $NICNames | Select-Object -ExpandProperty IPv4Connectivity
$Status = Get-NetConnectionProfile -InterfaceAlias $NICNames | Select-Object -ExpandProperty IPv4Connectivity

Filtering Adapters with Valid Profiles

You can also focusing only on NICs that have valid connection profiles. Adapters without profiles are skipped. For instance:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
# Get all connection profiles
$ConnectionProfiles = Get-NetConnectionProfile
# Get only NIC names that have associated connection profiles
$ValidNICNames = $ConnectionProfiles.InterfaceAlias
# Get all connection profiles $ConnectionProfiles = Get-NetConnectionProfile # Get only NIC names that have associated connection profiles $ValidNICNames = $ConnectionProfiles.InterfaceAlias
# Get all connection profiles
$ConnectionProfiles = Get-NetConnectionProfile

# Get only NIC names that have associated connection profiles
$ValidNICNames = $ConnectionProfiles.InterfaceAlias

Verifying Internet Connectivity

We use a do-until loop to continuously ping Google’s DNS server (8.8.8.8) until at least one NIC reports “Internet” as its connectivity status:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
do
{
ping 8.8.8.8
Sleep -Seconds 2
}
Until ($PingInternet -eq "Internet")
do { ping 8.8.8.8 Sleep -Seconds 2 } Until ($PingInternet -eq "Internet")
do 
{
    ping 8.8.8.8
    Sleep -Seconds 2
} 
Until ($PingInternet -eq "Internet")
  • The loop ensures that the system waits until full internet connectivity is achieved.
  • The delay (Sleep) reduces unnecessary system load during repeated checks.

Error Handling

To avoid script crashes, errors are gracefully handled. NICs without valid profiles are ignored, and warnings are displayed for better visibility:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
catch {
Write-Warning "No connection profile found for NIC '$NICName'."
}
catch { Write-Warning "No connection profile found for NIC '$NICName'." }
catch {
    Write-Warning "No connection profile found for NIC '$NICName'."
}

Outputting Results

The final output will display the connectivity status of all valid NICs, helping you identify which interfaces are operational and connected to the internet:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$CheckInternet | Select-Object -ExpandProperty IPv4Connectivity
$CheckInternet | Select-Object -ExpandProperty IPv4Connectivity
$CheckInternet | Select-Object -ExpandProperty IPv4Connectivity
  • The script filters and displays only NICs with active connectivity statuses.

The Script

Below is the full PowerShell script designed to automate network diagnostics and internet connectivity checks. It combines methods for querying all network interfaces, focusing on those with valid profiles, and repeatedly verifying internet access by pinging Google’s public DNS server (8.8.8.8).

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
# Set NIC Adapter variable
$NICAdapter = Get-NetAdapter
# Save the network adapter names to a variable
$NICNames = $NICAdapter | Select-Object -ExpandProperty Name
# Get all connection profiles
$ConnectionProfiles = Get-NetConnectionProfile
# Get only NIC names that have associated connection profiles
$ValidNICNames = $ConnectionProfiles.InterfaceAlias
# Initialize a variable to store IPv4Connectivity statuses
$CheckInternet = @()
# Loop through each valid NIC name and check IPv4Connectivity status
foreach ($NICName in $ValidNICNames)
{
try
{
# Get the IPv4Connectivity status for the current NIC
$Status = Get-NetConnectionProfile -InterfaceAlias $NICName | Select-Object -ExpandProperty IPv4Connectivity
# Add the result to the array
$CheckInternet += [PSCustomObject]@{
NICName = $NICName
IPv4Connectivity = $Status
}
}
catch
{
# Handle errors gracefully
Write-Warning "Failed to retrieve IPv4Connectivity for NIC '$NICName'."
}
}
# Output the results
$PingInternet = $CheckInternet | Select-Object -ExpandProperty IPv4Connectivity
#Ping to google do Loop until the NIC status shows Internet
do
{
Write-Host "Testing Internet connection by pinging 8.8.8.8..." -ForegroundColor Cyan
ping 8.8.8.8
Sleep -Seconds 2
}
Until ($PingInternet -eq "Internet")
Write-Host "NIC status shows $PingInternet." -ForegroundColor Green
Write-Host "Showing NIC status details" -ForegroundColor Green
$CheckInternet
# Set NIC Adapter variable $NICAdapter = Get-NetAdapter # Save the network adapter names to a variable $NICNames = $NICAdapter | Select-Object -ExpandProperty Name # Get all connection profiles $ConnectionProfiles = Get-NetConnectionProfile # Get only NIC names that have associated connection profiles $ValidNICNames = $ConnectionProfiles.InterfaceAlias # Initialize a variable to store IPv4Connectivity statuses $CheckInternet = @() # Loop through each valid NIC name and check IPv4Connectivity status foreach ($NICName in $ValidNICNames) { try { # Get the IPv4Connectivity status for the current NIC $Status = Get-NetConnectionProfile -InterfaceAlias $NICName | Select-Object -ExpandProperty IPv4Connectivity # Add the result to the array $CheckInternet += [PSCustomObject]@{ NICName = $NICName IPv4Connectivity = $Status } } catch { # Handle errors gracefully Write-Warning "Failed to retrieve IPv4Connectivity for NIC '$NICName'." } } # Output the results $PingInternet = $CheckInternet | Select-Object -ExpandProperty IPv4Connectivity #Ping to google do Loop until the NIC status shows Internet do { Write-Host "Testing Internet connection by pinging 8.8.8.8..." -ForegroundColor Cyan ping 8.8.8.8 Sleep -Seconds 2 } Until ($PingInternet -eq "Internet") Write-Host "NIC status shows $PingInternet." -ForegroundColor Green Write-Host "Showing NIC status details" -ForegroundColor Green $CheckInternet
# Set NIC Adapter variable
$NICAdapter = Get-NetAdapter

# Save the network adapter names to a variable
$NICNames = $NICAdapter | Select-Object -ExpandProperty Name

# Get all connection profiles
$ConnectionProfiles = Get-NetConnectionProfile

# Get only NIC names that have associated connection profiles
$ValidNICNames = $ConnectionProfiles.InterfaceAlias

# Initialize a variable to store IPv4Connectivity statuses
$CheckInternet = @()

# Loop through each valid NIC name and check IPv4Connectivity status
foreach ($NICName in $ValidNICNames) 
{
    try 
    {
        # Get the IPv4Connectivity status for the current NIC
        $Status = Get-NetConnectionProfile -InterfaceAlias $NICName | Select-Object -ExpandProperty IPv4Connectivity
        
        # Add the result to the array
        $CheckInternet += [PSCustomObject]@{
            NICName = $NICName
            IPv4Connectivity = $Status
        }
    } 
    catch 
    {
        # Handle errors gracefully
        Write-Warning "Failed to retrieve IPv4Connectivity for NIC '$NICName'."
    }
}

# Output the results
$PingInternet = $CheckInternet | Select-Object -ExpandProperty IPv4Connectivity

#Ping to google do Loop until the NIC status shows Internet
do
{
	Write-Host "Testing Internet connection by pinging 8.8.8.8..." -ForegroundColor Cyan

	ping 8.8.8.8

	Sleep -Seconds 2
}
Until ($PingInternet -eq "Internet")

Write-Host "NIC status shows $PingInternet." -ForegroundColor Green
Write-Host "Showing NIC status details" -ForegroundColor Green

$CheckInternet

Below is the output example:

Feel free to adapt this script to your specific use case by modifying the target IP for pinging, adding logging features, or integrating it into a larger automation framework.

Enhancements

While the script is functional and effective for its purpose, there are opportunities to improve and expand its capabilities:

Multi-Target Pinging

Instead of relying a single target (8.8.8.8), we can pinging multiple targets to test connectivity against different servers and ensure redundancy. For instance, the script below use Google Public DNS, Cloudflare and OpenDNS as ping targets:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$PingTargets = @("8.8.8.8", "1.1.1.1", "208.67.222.222")
do
{
foreach ($Target in $PingTargets) {
Write-Host "Pinging $Target..." -ForegroundColor Cyan
ping $Target
}
Sleep -Seconds 2
}
Until ($PingInternet -eq "Internet")
$PingTargets = @("8.8.8.8", "1.1.1.1", "208.67.222.222") do { foreach ($Target in $PingTargets) { Write-Host "Pinging $Target..." -ForegroundColor Cyan ping $Target } Sleep -Seconds 2 } Until ($PingInternet -eq "Internet")
$PingTargets = @("8.8.8.8", "1.1.1.1", "208.67.222.222")

do 
{
    foreach ($Target in $PingTargets) {
        Write-Host "Pinging $Target..." -ForegroundColor Cyan
        ping $Target
    }
    Sleep -Seconds 2
} 
Until ($PingInternet -eq "Internet")

Customizable Ping Targets

We can allow users to specify their own targets for connectivity checks, making the script flexible for different environments:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
# User-defined targets
$CustomTargets = Read-Host "Enter IP addresses or domain names to ping, separated by commas"
$PingTargets = $CustomTargets -split ","
do
{
foreach ($Target in $PingTargets) {
Write-Host "Pinging $Target..." -ForegroundColor Cyan
ping $Target
}
Sleep -Seconds 2
}
Until ($PingInternet -contains "Internet")
# User-defined targets $CustomTargets = Read-Host "Enter IP addresses or domain names to ping, separated by commas" $PingTargets = $CustomTargets -split "," do { foreach ($Target in $PingTargets) { Write-Host "Pinging $Target..." -ForegroundColor Cyan ping $Target } Sleep -Seconds 2 } Until ($PingInternet -contains "Internet")
# User-defined targets
$CustomTargets = Read-Host "Enter IP addresses or domain names to ping, separated by commas"
$PingTargets = $CustomTargets -split ","

do 
{
    foreach ($Target in $PingTargets) {
        Write-Host "Pinging $Target..." -ForegroundColor Cyan
        ping $Target
    }
    Sleep -Seconds 2
} 
Until ($PingInternet -contains "Internet")

Logging and Notifications

You can create logs and save to a file, and notifications sent via email or SMS when connectivity issues arise:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
# Logging
$LogFile = "C:\Logs\NetworkConnectivity.log"
Write-Output "$(Get-Date): Internet status: $PingInternet" | Out-File -Append -FilePath $LogFile
# Notifications
if ($PingInternet -ne "Internet")
{
Send-MailMessage -To "admin@example.com" `
-From "monitor@example.com" `
-Subject "Network Connectivity Issue" `
-Body "Internet is down!" `
-SmtpServer "smtp.example.com"
}
# Logging $LogFile = "C:\Logs\NetworkConnectivity.log" Write-Output "$(Get-Date): Internet status: $PingInternet" | Out-File -Append -FilePath $LogFile # Notifications if ($PingInternet -ne "Internet") { Send-MailMessage -To "admin@example.com" ` -From "monitor@example.com" ` -Subject "Network Connectivity Issue" ` -Body "Internet is down!" ` -SmtpServer "smtp.example.com" }
# Logging

$LogFile = "C:\Logs\NetworkConnectivity.log"
Write-Output "$(Get-Date): Internet status: $PingInternet" | Out-File -Append -FilePath $LogFile

# Notifications
if ($PingInternet -ne "Internet") 
{
    Send-MailMessage -To "admin@example.com" `
                     -From "monitor@example.com" `
                     -Subject "Network Connectivity Issue" `
                     -Body "Internet is down!" `
                     -SmtpServer "smtp.example.com"
}

Conclusion

In a nutshell, this blog offers a practical solution for automating network diagnostics, saving time and reducing errors in troubleshooting connectivity issues. By customizing and extending its features, it can become an indispensable tool for IT professionals and anyone managing complex network setups.

Leave a Reply

Your email address will not be published. Required fields are marked *