Skip to content

How to Check if IPv6 is Enabled in Batch Script

Learn how to verify IPv6 status in Windows using Batch scripts with netsh, ipconfig, and PowerShell for network troubleshooting and compatibility checks.

IPv6 is the modern standard for internet addressing, and Windows relies on it for many core features like DirectAccess, Nearby Sharing, and modern peer-to-peer networking. However, in some legacy environments, IPv6 is intentionally disabled to avoid compatibility issues. For a system administrator, knowing whether IPv6 is active on a specific network adapter is critical for ensuring application compatibility. A Batch script can query the network interface status to verify if the IPv6 stack is bound to the card and actively communicating.

This guide will explain how to audit IPv6 availability using native Batch and PowerShell.

Method 1: Using Netsh (Quick Status Check)

The netsh command can check if the IPv6 protocol is recognized on a specific interface.

@echo off
setlocal enabledelayedexpansion

set "Adapter=Ethernet"

echo [AUDIT] Checking IPv6 status for: "%Adapter%"...
echo.

:: First verify the adapter name exists
netsh interface show interface "%Adapter%" >nul 2>&1
if !errorlevel! neq 0 (
    echo [ERROR] Adapter "%Adapter%" not found.
    echo.
    echo Available interfaces:
    netsh interface show interface
    pause
    endlocal
    exit /b 1
)

:: Check if IPv6 is recognized on this adapter
set "IPv6Found=0"

:: Query IPv6 interface list and look for our adapter
netsh interface ipv6 show interface "%Adapter%" >nul 2>&1
if !errorlevel! equ 0 (
    set "IPv6Found=1"
)

:: Also check for an actual fe80: address as confirmation
set "HasAddress=0"
for /f "delims=" %%L in ('ipconfig ^| findstr /i "fe80:"') do (
    set "HasAddress=1"
)

if !IPv6Found! equ 1 (
    echo [OK] IPv6 is ENABLED on "%Adapter%".
    if !HasAddress! equ 1 (
        echo [OK] Link-Local address detected - IPv6 is actively working.
    ) else (
        echo [WARN] IPv6 is enabled but no Link-Local address found.
        echo        The adapter may be disconnected or IPv6 may not be functioning.
    )
) else (
    echo [ALERT] IPv6 is DISABLED or not recognized on "%Adapter%".
)

pause
endlocal

Method 2: Detecting via IPCONFIG (The "Presence" Check)

If an adapter is truly running IPv6, it will always have at least one address (usually starting with fe80:). This method checks all adapters at once.

@echo off
setlocal enabledelayedexpansion

echo [SCAN] Scanning all adapters for IPv6 status...
echo.

set "IPv6Count=0"
set "AdapterCount=0"

:: Count IPv6 addresses found across all adapters
for /f "delims=" %%L in ('ipconfig ^| findstr /i /c:"IPv6 Address" /c:"Link-local IPv6"') do (
    set /a IPv6Count+=1
)

:: Count active adapters
for /f "delims=" %%L in ('ipconfig ^| findstr /i /c:"adapter"') do (
    set /a AdapterCount+=1
)

echo   Active adapters found:    !AdapterCount!
echo   IPv6 addresses detected:  !IPv6Count!
echo.

if !IPv6Count! gtr 0 (
    echo [OK] IPv6 is actively running on this system.
    echo.
    echo --- IPv6 Addresses ---
    ipconfig | findstr /i /c:"IPv6 Address" /c:"Link-local IPv6"
    echo ----------------------
) else (
    echo [WARN] No active IPv6 addresses detected on any adapter.
    echo        IPv6 may be disabled system-wide or on all active adapters.
)

pause
endlocal

Method 3: Deep Protocol Audit (PowerShell Bridge)

If you need to know if the protocol is technically "enabled" (checked in the adapter properties GUI) versus just having an address, PowerShell's Get-NetAdapterBinding is the most accurate tool.

@echo off
setlocal EnableDelayedExpansion

echo ============================================================
echo   Deep IPv6 Protocol Binding Audit
echo ============================================================
echo.
echo Computer: %COMPUTERNAME%
echo Date:     %date% %time%
echo.
echo ============================================================
echo.

echo [AUDIT] Analyzing IPv6 configuration across all network adapters...
echo.

:: Create PowerShell script for better readability
set "PSScript=%TEMP%\ipv6_audit_%RANDOM%.ps1"

(
echo try {
echo     $adapters = Get-NetAdapter -ErrorAction SilentlyContinue ^| 
echo         Where-Object { $_.Status -eq 'Up' -or $_.Status -eq 'Disconnected' }
echo     
echo     if (-not $adapters^) {
echo         Write-Host '[ERROR] No network adapters found.' -ForegroundColor Red
echo         exit 1
echo     }
echo     
echo     Write-Host "============================================================" -ForegroundColor Cyan
echo     Write-Host "  Network Adapter IPv6 Status" -ForegroundColor Cyan
echo     Write-Host "============================================================" -ForegroundColor Cyan
echo     Write-Host ""
echo     
echo     # Header
echo     $header = "{0,-4} {1,-30} {2,-15} {3,-12} {4,-12} {5}" -f 
echo         'STAT', 'ADAPTER NAME', 'STATUS', 'IPv6 BOUND', 'HAS ADDRESS', 'IPv6 ADDRESS'
echo     Write-Host $header -ForegroundColor White
echo     Write-Host ('-' * 100^) -ForegroundColor Gray
echo     
echo     $warnings = 0
echo     $totalAdapters = 0
echo     $boundAdapters = 0
echo     $activeIPv6 = 0
echo     
echo     foreach ($a in $adapters^) {
echo         $totalAdapters++
echo         
echo         # Check if IPv6 protocol is bound (enabled in properties^)
echo         $binding = Get-NetAdapterBinding -Name $a.Name -ComponentID ms_tcpip6 -ErrorAction SilentlyContinue
echo         $isBound = if ($binding^) { $binding.Enabled } else { $false }
echo         
echo         if ($isBound^) { $boundAdapters++ }
echo         
echo         # Check for actual IPv6 address
echo         $ipv6Addresses = Get-NetIPAddress -InterfaceIndex $a.InterfaceIndex -AddressFamily IPv6 -ErrorAction SilentlyContinue ^|
echo             Where-Object { $_.AddressState -eq 'Preferred' }
echo         
echo         $linkLocal = $ipv6Addresses ^| Where-Object { $_.IPAddress -like 'fe80::*' } ^| Select-Object -First 1
echo         $globalAddr = $ipv6Addresses ^| Where-Object { $_.IPAddress -notlike 'fe80::*' -and $_.IPAddress -notlike 'ff*' } ^| Select-Object -First 1
echo         
echo         $hasAddr = [bool]$linkLocal -or [bool]$globalAddr
echo         
echo         if ($hasAddr^) { $activeIPv6++ }
echo         
echo         # Determine address to display
echo         if ($globalAddr^) {
echo             $addrStr = $globalAddr.IPAddress + " (Global^)"
echo         } elseif ($linkLocal^) {
echo             $addrStr = $linkLocal.IPAddress + " (Link-Local^)"
echo         } else {
echo             $addrStr = "None"
echo         }
echo         
echo         # Determine status icon
echo         if ($isBound -and $hasAddr^) {
echo             $icon = "[OK]"
echo             $color = "Green"
echo         } elseif ($isBound -and -not $hasAddr^) {
echo             $icon = "[!!]"
echo             $color = "Yellow"
echo         } else {
echo             $icon = "[--]"
echo             $color = "Gray"
echo         }
echo         
echo         # Display row
echo         $row = "{0,-4} {1,-30} {2,-15} {3,-12} {4,-12} {5}" -f 
echo             $icon, 
echo             ($a.Name.Substring(0, [Math]::Min(28, $a.Name.Length^)^)^), 
echo             $a.Status, 
echo             $isBound, 
echo             $hasAddr, 
echo             $addrStr
echo         
echo         Write-Host $row -ForegroundColor $color
echo         
echo         # Add warnings
echo         if ($isBound -and -not $hasAddr -and $a.Status -eq 'Up'^) {
echo             Write-Host "     WARNING: IPv6 bound but no address - check connectivity" -ForegroundColor Yellow
echo             $warnings++
echo         }
echo         
echo         if (-not $isBound -and $a.Status -eq 'Up'^) {
echo             Write-Host "     INFO: IPv6 disabled on this active adapter" -ForegroundColor Cyan
echo         }
echo     }
echo     
echo     Write-Host ('-' * 100^) -ForegroundColor Gray
echo     Write-Host ""
echo     
echo     # Check for IPv6 tunneling adapters
echo     Write-Host "============================================================" -ForegroundColor Cyan
echo     Write-Host "  IPv6 Transition Technologies" -ForegroundColor Cyan
echo     Write-Host "============================================================" -ForegroundColor Cyan
echo     Write-Host ""
echo     
echo     $tunnels = Get-NetAdapter -ErrorAction SilentlyContinue ^|
echo         Where-Object { $_.InterfaceDescription -match 'Teredo^|6to4^|ISATAP' }
echo     
echo     if ($tunnels^) {
echo         Write-Host "Detected IPv6 transition adapters:" -ForegroundColor Yellow
echo         foreach ($t in $tunnels^) {
echo             Write-Host ("  - {0}" -f $t.Name^) -ForegroundColor Yellow
echo             Write-Host ("    Type:   {0}" -f $t.InterfaceDescription^) -ForegroundColor Gray
echo             Write-Host ("    Status: {0}" -f $t.Status^) -ForegroundColor Gray
echo             
echo             $binding = Get-NetAdapterBinding -Name $t.Name -ComponentID ms_tcpip6 -ErrorAction SilentlyContinue
echo             if ($binding -and $binding.Enabled^) {
echo                 Write-Host "    Bound:  Yes (providing IPv6 over IPv4^)" -ForegroundColor Gray
echo             }
echo         }
echo         Write-Host ""
echo         Write-Host "NOTE: These provide IPv6 over IPv4 tunneling, not native IPv6" -ForegroundColor Cyan
echo     } else {
echo         Write-Host "No IPv6 transition adapters detected" -ForegroundColor Green
echo     }
echo     
echo     Write-Host ""
echo     
echo     # Summary statistics
echo     Write-Host "============================================================" -ForegroundColor Cyan
echo     Write-Host "  Summary" -ForegroundColor Cyan
echo     Write-Host "============================================================" -ForegroundColor Cyan
echo     Write-Host ""
echo     Write-Host ("Total Adapters:           {0}" -f $totalAdapters^)
echo     Write-Host ("IPv6 Bound (Enabled^):     {0}" -f $boundAdapters^)
echo     Write-Host ("Active IPv6 Addresses:    {0}" -f $activeIPv6^)
echo     Write-Host ("Warnings:                 {0}" -f $warnings^)
echo     Write-Host ""
echo     
echo     # Overall assessment
echo     if ($warnings -gt 0^) {
echo         Write-Host "Assessment: WARNINGS FOUND" -ForegroundColor Yellow
echo         Write-Host "Action: Investigate flagged adapters" -ForegroundColor Yellow
echo         exit 1
echo     } elseif ($activeIPv6 -eq 0 -and $boundAdapters -gt 0^) {
echo         Write-Host "Assessment: IPv6 ENABLED BUT NOT FUNCTIONAL" -ForegroundColor Yellow
echo         Write-Host "Action: Check network connectivity and router configuration" -ForegroundColor Yellow
echo         exit 1
echo     } elseif ($boundAdapters -eq 0^) {
echo         Write-Host "Assessment: IPv6 DISABLED" -ForegroundColor Cyan
echo         Write-Host "Info: IPv6 is not enabled on any adapters" -ForegroundColor Cyan
echo         exit 0
echo     } else {
echo         Write-Host "Assessment: PASS" -ForegroundColor Green
echo         Write-Host "Info: IPv6 configuration appears normal" -ForegroundColor Green
echo         exit 0
echo     }
echo     
echo } catch {
echo     Write-Host "ERROR: Failed to query network adapters" -ForegroundColor Red
echo     Write-Host ("Error: {0}" -f $_.Exception.Message^) -ForegroundColor Red
echo     exit 2
echo }
) > "%PSScript%"

:: Execute PowerShell script
powershell -NoProfile -ExecutionPolicy Bypass -File "%PSScript%"
set "AuditResult=!errorlevel!"

:: Cleanup
del "%PSScript%" >nul 2>&1

echo.
echo ============================================================
echo   Audit Complete
echo ============================================================
echo.

if !AuditResult! equ 0 (
    echo Result: PASS
) else if !AuditResult! equ 1 (
    echo Result: WARNING - Review flagged items
) else (
    echo Result: ERROR - Unable to complete audit
)

echo.
pause
endlocal
exit /b !AuditResult!

Method 4: Registry-Level Check (System-Wide IPv6 Status)

IPv6 can be disabled system-wide via a registry key. This checks the actual system configuration regardless of individual adapter settings.

@echo off
setlocal EnableDelayedExpansion

echo ============================================================
echo   IPv6 System-Wide Registry Configuration Audit
echo ============================================================
echo.
echo Computer: %COMPUTERNAME%
echo Date:     %date% %time%
echo.
echo ============================================================
echo.

set "RegKey=HKLM\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters"
set "RegValue=DisabledComponents"

echo [AUDIT] Checking registry configuration...
echo.
echo Registry Key:   %RegKey%
echo Registry Value: %RegValue%
echo.

:: Query the registry for the IPv6 disable flag
set "DisableFlag="
for /f "skip=2 tokens=3" %%a in (
    'reg query "%RegKey%" /v "%RegValue%" 2^>nul'
) do (
    set "DisableFlag=%%a"
)

if not defined DisableFlag (
    echo ============================================================
    echo   Result: Default Configuration
    echo ============================================================
    echo.
    echo [OK] Registry value "%RegValue%" is NOT set
    echo.
    echo This is the default Windows configuration.
    echo IPv6 is ENABLED at the system level.
    echo.
    echo What this means:
    echo   - IPv6 is active on all network adapters
    echo   - Both native and tunnel interfaces are enabled
    echo   - System can use IPv6 for network communication
    echo.
    set "ConfigStatus=ENABLED_DEFAULT"
    
) else (
    echo ============================================================
    echo   Result: Custom Configuration Detected
    echo ============================================================
    echo.
    echo Registry Value: %RegValue% = !DisableFlag!
    echo.
    
    :: Convert hex to decimal for easier comparison
    set "DecValue="
    for /f %%d in ('powershell -NoProfile -Command "[Convert]::ToInt32('!DisableFlag!'.Replace('0x',''^^), 16)"') do set "DecValue=%%d"
    
    if defined DecValue (
        echo Decimal Value:  !DecValue!
        echo.
    )
    
    :: Interpret the value based on Microsoft documentation
    :: Reference: https://support.microsoft.com/kb/929852
    
    if /i "!DisableFlag!"=="0xff" (
        echo ============================================================
        echo   IPv6 Status: COMPLETELY DISABLED
        echo ============================================================
        echo.
        echo [CRITICAL] All IPv6 components are DISABLED system-wide
        echo.
        echo Disabled Components:
        echo   - All IPv6 interfaces ^(physical and virtual^)
        echo   - All IPv6 tunnel interfaces ^(Teredo, 6to4, ISATAP^)
        echo   - IPv6 protocol stack
        echo   - IPv6 routing
        echo.
        echo Impact:
        echo   - No IPv6 connectivity possible
        echo   - Only IPv4 will be used for all network traffic
        echo   - Some modern applications may have reduced functionality
        echo.
        set "ConfigStatus=FULLY_DISABLED"
        
    ) else if /i "!DisableFlag!"=="0x20" (
        echo ============================================================
        echo   IPv6 Status: DISABLED ON NON-TUNNEL INTERFACES
        echo ============================================================
        echo.
        echo [WARNING] IPv6 is disabled on physical/native interfaces
        echo.
        echo Disabled:
        echo   - IPv6 on Ethernet adapters
        echo   - IPv6 on Wi-Fi adapters
        echo   - Native IPv6 connectivity
        echo.
        echo Still Enabled:
        echo   - IPv6 tunnel interfaces ^(Teredo, 6to4^)
        echo   - IPv6 over IPv4 tunneling
        echo.
        echo Impact:
        echo   - No native IPv6 connectivity
        echo   - Tunneled IPv6 may still work
        echo   - Prefer IPv4 over IPv6
        echo.
        set "ConfigStatus=NATIVE_DISABLED"
        
    ) else if /i "!DisableFlag!"=="0x10" (
        echo ============================================================
        echo   IPv6 Status: TUNNEL INTERFACES DISABLED
        echo ============================================================
        echo.
        echo [INFO] IPv6 tunnel interfaces are disabled
        echo.
        echo Disabled:
        echo   - Teredo tunneling
        echo   - 6to4 tunneling
        echo   - ISATAP
        echo.
        echo Still Enabled:
        echo   - Native IPv6 on physical adapters
        echo   - Link-local IPv6 addresses
        echo   - IPv6 routing
        echo.
        echo Impact:
        echo   - Native IPv6 works normally
        echo   - IPv6 over IPv4 tunneling blocked
        echo   - Improved security ^(tunnels often bypassed^)
        echo.
        set "ConfigStatus=TUNNELS_DISABLED"
        
    ) else if /i "!DisableFlag!"=="0x1" (
        echo ============================================================
        echo   IPv6 Status: TUNNELS DISABLED ^(Alternate Value^)
        echo ============================================================
        echo.
        echo [INFO] IPv6 tunnel interfaces disabled ^(value 0x1^)
        echo.
        echo Similar to 0x10 - disables IPv6 transition technologies
        echo.
        set "ConfigStatus=TUNNELS_DISABLED_ALT"
        
    ) else if /i "!DisableFlag!"=="0x0" (
        echo ============================================================
        echo   IPv6 Status: EXPLICITLY ENABLED
        echo ============================================================
        echo.
        echo [OK] IPv6 is fully enabled ^(explicitly set to 0^)
        echo.
        echo All IPv6 components are active:
        echo   - Native IPv6 on all adapters
        echo   - Tunnel interfaces enabled
        echo   - Full IPv6 protocol stack
        echo.
        set "ConfigStatus=ENABLED_EXPLICIT"
        
    ) else if /i "!DisableFlag!"=="0x11" (
        echo ============================================================
        echo   IPv6 Status: PREFER IPv4, TUNNELS DISABLED
        echo ============================================================
        echo.
        echo [INFO] Combined configuration ^(0x10 + 0x01^)
        echo.
        echo Configuration:
        echo   - Prefer IPv4 over IPv6
        echo   - Tunnel interfaces disabled
        echo   - Native IPv6 still functional
        echo.
        set "ConfigStatus=PREFER_IPV4"
        
    ) else (
        echo ============================================================
        echo   IPv6 Status: CUSTOM CONFIGURATION
        echo ============================================================
        echo.
        echo [INFO] Non-standard DisabledComponents value detected
        echo.
        echo Value: !DisableFlag! (Decimal: !DecValue!^)
        echo.
        echo Common values:
        echo   0x00 ^(0^)   = All enabled
        echo   0x01 ^(1^)   = Tunnels disabled ^(method 1^)
        echo   0x10 ^(16^)  = Tunnels disabled ^(method 2^)
        echo   0x11 ^(17^)  = Prefer IPv4, tunnels off
        echo   0x20 ^(32^)  = Native IPv6 disabled
        echo   0xFF ^(255^) = All IPv6 disabled
        echo.
        echo Reference: Microsoft KB929852
        echo.
        set "ConfigStatus=CUSTOM"
    )
)

echo.

:: Check IPv6 prefix policy (preference settings)
echo ============================================================
echo   IPv6 Prefix Policy Check
echo ============================================================
echo.
echo [CHECK] Analyzing IPv6 preference settings...
echo.

:: Check if IPv4-mapped IPv6 addresses are present (indicates IPv4 preference)
netsh interface ipv6 show prefixpolicy 2>nul | findstr /C:"::ffff:0:0" >nul 2>&1

if !errorlevel! equ 0 (
    echo [INFO] IPv4-mapped prefix detected in policy table
    echo.
    echo This may indicate:
    echo   - System prefers IPv4 over IPv6 for dual-stack connections
    echo   - IPv6 has lower priority in DNS resolution
    echo.
    echo View full policy:
    echo   netsh interface ipv6 show prefixpolicy
    echo.
) else (
    echo [OK] No explicit IPv4 preference detected
    echo.
)

:: Summary
echo ============================================================
echo   Summary
echo ============================================================
echo.
echo Configuration: !ConfigStatus!
echo.

if "!ConfigStatus!"=="ENABLED_DEFAULT" (
    echo Assessment: IPv6 is using default Windows configuration
    echo Action:     No changes needed unless IPv6 is not required
    set "ExitCode=0"
    
) else if "!ConfigStatus!"=="ENABLED_EXPLICIT" (
    echo Assessment: IPv6 is explicitly enabled
    echo Action:     Configuration is clear and intentional
    set "ExitCode=0"
    
) else if "!ConfigStatus!"=="FULLY_DISABLED" (
    echo Assessment: IPv6 is completely disabled
    echo Action:     Enable IPv6 if needed, or document this decision
    set "ExitCode=1"
    
) else if "!ConfigStatus!"=="TUNNELS_DISABLED" (
    echo Assessment: Security-focused configuration
    echo Action:     Tunnels disabled, native IPv6 works
    set "ExitCode=0"
    
) else (
    echo Assessment: Custom configuration in use
    echo Action:     Review and document this setting
    set "ExitCode=0"
)

echo.
echo ============================================================
echo.

pause
endlocal
exit /b %ExitCode%

How to Avoid Common Errors

Wrong Way: Assuming a ::1 Ping Test Is Enough

Pinging ::1 (IPv6 localhost) will work even if your network adapter has IPv6 disabled. This only tests the software stack, not the physical connection.

Correct Way: Use Method 1 or Method 3 to check the specific binding on the network adapter. This tells you if actual traffic can flow out of the computer using IPv6.

Wrong Way: Checking "IPv6 Enabled" Without Checking for an Address

An adapter can have IPv6 enabled in its properties but not have an active address: if the cable is unplugged, the driver is broken, or a registry override is blocking it.

Correct Way: Check both the binding status (is IPv6 enabled?) AND the presence of an fe80: address (is it actually working?). Method 3 does both.

Wrong Way: Hardcoding the Adapter Name

"Ethernet" on your machine might be "Ethernet 2," "Local Area Connection," or "Wi-Fi" on another machine.

Correct Way: Either enumerate all adapters automatically (Methods 2–3) or validate the adapter name before using it:

netsh interface show interface "%Adapter%" >nul 2>&1
if %errorlevel% neq 0 echo Adapter not found.

Problem: Multiple Adapters

Identifying the status of "IPv6" globally is misleading if it's enabled on Ethernet but disabled on the Wi-Fi adapter you're actually using.

Solution: Always either specify the adapter name or enumerate all adapters with their individual status (Method 3).

Best Practices and Rules

1. Verify "Preferred" Protocol

Sometimes IPv6 is enabled but the system prefers IPv4. Check which protocol is used first:

:: If this returns an IPv4 address, your system prefers IPv4
nslookup google.com 2>nul | findstr "Address"

To check the prefix policy (which determines IPv4 vs. IPv6 preference):

netsh interface ipv6 show prefixpolicy

2. Administrator Privileges

Querying adapter bindings (Get-NetAdapterBinding) and deep netsh properties usually requires running the script as an Administrator. Basic ipconfig checks (Method 2) work without elevation.

3. Identify Tunneling Adapters

Watch out for 6to4, Teredo, or ISATAP tunneling adapters. These "virtual" adapters provide IPv6 connectivity over an IPv4 connection. Your report should distinguish between native hardware IPv6 and these transition technologies. Method 3 automatically detects and flags tunneling adapters.

4. Registry Override Awareness

Corporate Group Policy can disable IPv6 system-wide via the DisabledComponents registry key without changing adapter bindings. Always check Method 4 if per-adapter checks show IPv6 as enabled but it's not functioning.

5. Don't Disable IPv6 Without Reason

Microsoft officially states that IPv6 is a mandatory part of Windows and disabling it may cause issues. Features that depend on IPv6 include:

  • DirectAccess VPN
  • Nearby Sharing
  • Windows Peer Name Resolution (PNRP)
  • Some Windows Update scenarios

6. Always Use setlocal / endlocal

Without setlocal, every variable your script creates persists in the parent shell session, causing potential conflicts when running multiple scripts in sequence.

Conclusions

Checking if IPv6 is enabled is a foundational step in modern network troubleshooting. By moving beyond legacy IPv4 checks and verifying the binding status of the modern protocol stack, you gain the clarity needed to resolve connectivity issues and maintain compatibility with modern applications. This professional auditing ensures that your network infrastructure is fully utilizing the capabilities of the Windows operating system.

Navigation