Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / programming / Internet

Test for Internet Connectivity the Windows Way

3.33/5 (4 votes)
13 Feb 2016CPOL4 min read 19.3K   524  
A PowerShell function for testing Internet connectivity using the Network Connectivity Status Indicator (NCSI) mechanism

Introduction

Sometimes, you need the information whether a box is connected to the Internet or not. Of course, you could use the build in PowerShell Test-NetConnection cmdlet with a static URL to a web server. However, the Test-InternetConnection function uses the same mechanism like the Windows operating system to determine the Internet connection status and respects any changes in this mechanism made by administrators via GPO or Registry.

Background

The Test-InternetConnection function uses the same mechanism like the Windows Network Connectivity Status Indicator (NCSI) for the detection of an Internet. The NCSI is used within the Network Awareness API and shows the Internet connectivity with the Network Connection Status Icon in the system tray. This mechanism can be configured by registry keys of the “Network Location Awareness” service.
The internet connectivity is determined by four steps:

Image 1

In the first step, a IP4 HTTP request is compared to a known string stored in the registry. If the request returns the expected characters, the Internet connection is considered to be available. If the request fails, the same mechanism is used with an IP6 URL. If both fail, the third step tries to resolve an IP4 DNS name and, if this fails again, an IP6 DNS resolution is used. If all four steps fail, then the Internet connection is considered to be not available.

The HTTP hosts, URLs, contents and expected IPs of DNS name resolution are defined in the Windows Registry under the Key HKLM:\SYSTEM\CurrentControlSet\Services\NlaSvc\Parameters\Internet:

Method Name Data
IP4 HTTP Request ActiveWebProbeHost www.msftncsi.com
IP4 HTTP Request ActiveWebProbePath ncsi.txt
IP4 HTTP Request ActiveWebProbeContent Microsoft NCSI
IP6 HTTP Request ActiveWebProbeHostV6 www.msftncsi.com
IP6 HTTP Request ActiveWebProbePathV6 ncsi.txt
IP6 HTTP Request ActiveWebProbeContentV6 Microsoft NCSI
IP4 DNS Resolution ActiveDnsProbeHost dns.msftncsi.com
IP4 DNS Resolution ActiveDnsProbeContent 131.107.255.255
IP6 DNS Resolution ActiveDnsProbeHostV6 dns.msftncsi.com
IP6 DNS Resolution ActiveDnsProbeContentV6 fd3e:4f5a:5b81::1

These registry keys can be adjusted according to network requirements. Thus, other static URLs should not be used for the testing of Internet connectivity.

Script Code

The PowerShell Test-InternetConnection.ps1 script implements a function for the use in other scripts or the PowerShell console. Verbose information is enabled by the <font face="Courier New">[cmdletbinding()]</font> attribute:

JavaScript
function Test-InternetConnection {
    [cmdletbinding()]
    Param()

A HTTP request is submitted with the Invoke-Webrequest cmdlet which is available since PowerShell 3. The response content of the request is compared to the data of the corresponding registry key:

(Invoke-Webrequest ("http://{0}/{1}" 
-f (Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Services\NlaSvc\Parameters\Internet).ActiveWebProbeHost,
(Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Services\NlaSvc\Parameters\Internet).ActiveWebProbePath)
).Content 
-eq (Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Services\NlaSvc\Parameters\Internet).ActiveWebProbeContent

The same method is used for IP6 web request. If both requests fail, a DNS resolution is executed with the Resolve-DnsName cmdlet. This cmdlet lets you specify IP4 or IP6 DNS entries by the -Type parameter. The type A returns the IP4 address:

(Resolve-DnsName -Type A -ErrorAction SilentlyContinue 
(Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Services\NlaSvc\Parameters\Internet).
ActiveDnsProbeHost).IPAddress -eq 
(Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Services\NlaSvc\Parameters\Internet).
ActiveDnsProbeContent

The error action is set silently continue. This ensures that the next method is hit regardless of an exception. In the last block, the IP6 address is resolved with type AAAA.

If all methods fail, the function returns $Null otherwise it returns $True. This is handy for testing the Internet connection with an If statement.

Usage

The Test-InternetConnection function can be used via dot sourcing in the PowerShell command line or other scripts:

PS C:\>. .\Test-InternetConnection.ps1

After dot sourcing the function, it can be used like any other cmdlets.

The first and obvious usage is a test whether the computer has a valid Internet connection or not:

PS C:\> Test-InternetConnection
True

The return value is $True if an Internet connection is available, otherwise nothing is returned.

The second usage is within a script. There, the function can be used to determine the Internet connection status before other functions depending on an Internet connection are called:

PowerShell
# Dot sourcing Test-InternetConnection
. .\Test-InternetConnection.ps1

# Use Test-InternetConnection in a script
if(Test-InternetConnection) {
    Write-Host "Internet connection available"

    # More operations depending on a valid Internet connection
    # ...

} else {
    Write-Host "Internet connection not available"
}

Finally, the function can be used to debug Network Connectivity Status Indicator (NCSI). With the -Verbose flag, the function shows all methods which are successful or failing during the test:

PS C:\> Test-InternetConnection -Verbose
VERBOSE: GET http://www.msftncsi.com/ncsi.txt with 0-byte payload
VERBOSE: received 14-byte response of content type text/plain
VERBOSE: IP4 web probe succeeded.

True
PS C:\> Test-InternetConnection -Verbose
VERBOSE: GET http://www.msftncsi.com/ncsi.txt with 0-byte payload
VERBOSE: IP4 web probe failed.
VERBOSE: GET http://ipv6.msftncsi.com/ncsi.txt with 0-byte payload
VERBOSE: IP6 web probe failed.
VERBOSE: IP4 name resolution failed. VERBOSE: IP6 name resolution failed.

References

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)