PowerShell Network

Mouseless network control on Windows. Adapters, IP configuration, diagnostics, firewall, VPN, LAN, and proxy — everything you’d reach for ncpa.cpl or the system tray to do.

Sub-topic pages

WiFi and Bluetooth have their own dedicated pages:

  • WiFi — profiles, enterprise 802.1X, scan-before-connect, signal monitoring

  • Bluetooth — peripheral toggle, radio control, audio switching

Network Quick Reference

IP Configuration

Quick IP overview — active adapters only
Get-NetIPAddress -AddressFamily IPv4 |
    Where-Object { $_.IPAddress -ne '127.0.0.1' } |
    Select-Object InterfaceAlias, IPAddress, PrefixLength | Format-Table
Full IP config with gateway and DNS (expanded — no MSFT objects)
Get-NetIPConfiguration | Where-Object { $_.IPv4Address } | ForEach-Object {
    [PSCustomObject]@{
        Interface = $_.InterfaceAlias
        IPv4      = $_.IPv4Address.IPAddress
        Gateway   = $_.IPv4DefaultGateway.NextHop
        DNS       = ($_.DNSServer.ServerAddresses -join ', ')
    }
} | Format-Table -AutoSize
Get-NetIPConfiguration | Select-Object InterfaceAlias, IPv4Address, IPv4DefaultGateway, DNSServer outputs MSFT_* objects — useless. Always expand nested properties with ForEach-Object or use Format-List.
MAC addresses — all interfaces
Getmac
# PowerShell equivalent with status:
Get-NetAdapter | Select-Object Name, MacAddress, Status | Format-Table

Adapters

Adapter status
Get-NetAdapter | Select-Object Name, Status, LinkSpeed, MacAddress | Format-Table
Get-NetAdapter | Where-Object Status -eq Up
Get-NetAdapter -Physical                                         (1)
1 Filters out Hyper-V, WSL, VPN tunnel adapters — shows only hardware NICs
Toggle adapter (mouseless ncpa.cpl replacement)
Disable-NetAdapter -Name "Wi-Fi" -Confirm:$false
Enable-NetAdapter -Name "Wi-Fi" -Confirm:$false
Restart-NetAdapter -Name "Wi-Fi"                                 (1)
1 Restart = disable + enable — like unplugging the cable

DNS

DNS servers per interface
Get-DnsClientServerAddress -AddressFamily IPv4 |
    Where-Object { $_.ServerAddresses } |
    Select-Object InterfaceAlias, ServerAddresses | Format-Table
Resolve and cache operations
Resolve-DnsName github.com
Resolve-DnsName -Name github.com -Type MX                        (1)
Clear-DnsClientCache
Get-DnsClientCache | Select-Object Entry, Data | Format-Table    (2)
1 Query specific record types: A, AAAA, MX, TXT, CNAME, SRV, NS, SOA, PTR
2 View what’s cached before clearing — useful for troubleshooting stale records

WiFi

Current connection
netsh wlan show interfaces | Select-String -Pattern "State|SSID|Signal|Authentication|Channel"
Saved profiles
netsh wlan show profiles
netsh wlan show profile name="CHLA_Staff"                        (1)
netsh wlan show profile name="test-wifi" key=clear               (2)
1 Inspect enterprise profile — shows 802.1X, EAP type, cipher
2 key=clear reveals plaintext password for PSK profiles (Admin required)
Connect — scan-before-connect gotcha
# This FAILS if the adapter hasn't scanned recently:
#   netsh wlan connect name="CHLA-Remote" interface="Wi-Fi"
#   → "The network specified by profile is not available to connect."

# Fix: disconnect first to force a fresh scan, then reconnect
netsh wlan disconnect interface="Wi-Fi"
Start-Sleep -Seconds 3
netsh wlan connect name="CHLA-Remote" interface="Wi-Fi"
netsh wlan connect does not trigger a network scan. If the adapter hasn’t scanned since boot or since moving locations, the connect will fail silently. Disconnect first — the adapter scans automatically when disconnected.
Export all WiFi profiles (backup before reimaging)
netsh wlan export profile folder="$env:TEMP" key=clear

802.1X Status

Wired and wireless 802.1X
netsh lan show interfaces                                        (1)
netsh wlan show interfaces | Select-String -Pattern "Authentication|State|SSID"
Get-Service -Name "dot3svc" | Select-Object Name, Status, StartType  (2)
1 Shows wired 802.1X state — "does not support authentication" means EAP profile not applied or dot3svc not running
2 dot3svc = Wired AutoConfig — must be Running for wired 802.1X

Bluetooth — Mouseless Peripheral Control

List actual devices (filter out GATT services noise)
Get-PnpDevice -Class Bluetooth |
    Where-Object { $_.FriendlyName -notmatch 'Generic|Enumerator|RFCOMM|Service|Profile|Attribute' } |
    Select-Object Status, FriendlyName | Format-Table
Raw Get-PnpDevice -Class Bluetooth returns 30+ entries (GATT services, profiles, enumerators). The filter above shows only your actual hardware — earbuds, keyboard, mouse.
Toggle device (reconnect without GUI)
$dev = Get-PnpDevice -Class Bluetooth | Where-Object FriendlyName -like "*Buds4*"
Disable-PnpDevice -InstanceId $dev.InstanceId -Confirm:$false
Start-Sleep -Seconds 2
Enable-PnpDevice -InstanceId $dev.InstanceId -Confirm:$false
Toggle Bluetooth radio (kill switch)
$radio = Get-PnpDevice -Class Bluetooth | Where-Object FriendlyName -like '*Intel*Wireless*Bluetooth*'
if ($radio.Status -eq 'OK') {
    Disable-PnpDevice -InstanceId $radio.InstanceId -Confirm:$false
    Write-Host "Bluetooth OFF"
} else {
    Enable-PnpDevice -InstanceId $radio.InstanceId -Confirm:$false
    Write-Host "Bluetooth ON"
}
Switch audio output to Bluetooth headphones
# One-time: Install-Module -Name AudioDeviceCmdlets -Force
Get-AudioDevice -List                                            (1)
Set-AudioDevice -ID "{GUID-from-list}"
1 Lists all playback/recording endpoints with GUIDs — find your Bluetooth audio device, then set it

Connectivity Testing

Quick checks
Test-NetConnection -ComputerName github.com -Port 443
Test-NetConnection -ComputerName 10.50.1.20 -Port 8443 -InformationLevel Detailed  (1)
Test-Connection -ComputerName vault-01 -Count 4                  (2)
1 Detailed shows NameResolution, NetRoute NextHop, NetworkIsolationContext, IsAdmin
2 ICMP ping — equivalent to ping -c 4
Trace route
Test-NetConnection -ComputerName github.com -TraceRoute
What’s using a port?
Get-NetTCPConnection -LocalPort 8080 |
    Select-Object LocalPort, RemoteAddress, State,
    @{N='Process';E={(Get-Process -Id $_.OwningProcess).ProcessName}}

Firewall

View enabled rules
Get-NetFirewallRule | Where-Object Enabled -eq True |
    Select-Object DisplayName, Direction, Action | Format-Table
Get-NetFirewallRule -DisplayName "*Remote Desktop*"
Create rule
New-NetFirewallRule -DisplayName "Allow HTTPS Inbound" `
    -Direction Inbound -Protocol TCP -LocalPort 443 -Action Allow

Certificates (Quick)

List machine certs with expiry
Get-ChildItem Cert:\LocalMachine\My |
    Select-Object Subject, NotAfter, Thumbprint |
    Sort-Object NotAfter | Format-Table
Certs expiring within 30 days
$threshold = (Get-Date).AddDays(30)
Get-ChildItem Cert:\LocalMachine\My |
    Where-Object { $_.NotAfter -lt $threshold } |
    Select-Object Subject, NotAfter, Thumbprint
Find client auth certs (802.1X EAP-TLS)
Get-ChildItem Cert:\LocalMachine\My | Where-Object {
    $_.EnhancedKeyUsageList.FriendlyName -contains "Client Authentication"
} | Select-Object Subject, Issuer, NotAfter, Thumbprint

Network Adapters (ncpa.cpl Replacement)

List all network adapters (ncpa.cpl killer)
Get-NetAdapter | Format-Table Name, InterfaceDescription, Status, LinkSpeed, MacAddress
Get detailed adapter info
Get-NetAdapter | Select-Object Name, Status, MacAddress, LinkSpeed,
    @{N='Driver';E={$_.DriverDescription}},
    @{N='VLAN';E={$_.VlanID}}
Get specific adapter by name
Get-NetAdapter -Name "Wi-Fi"
Get-NetAdapter -Name "Ethernet*"
Get adapters with IP configuration combined
Get-NetAdapter | Where-Object Status -eq 'Up' | ForEach-Object {
    $ip = Get-NetIPAddress -InterfaceIndex $_.ifIndex -AddressFamily IPv4 -ErrorAction SilentlyContinue
    [PSCustomObject]@{
        Adapter  = $_.Name
        Status   = $_.Status
        Speed    = $_.LinkSpeed
        MAC      = $_.MacAddress
        IPv4     = $ip.IPAddress
        Prefix   = $ip.PrefixLength
    }
} | Format-Table
Enable/disable adapter (Admin)
Disable-NetAdapter -Name "Ethernet" -Confirm:$false
Enable-NetAdapter -Name "Ethernet" -Confirm:$false
Rename adapter
Rename-NetAdapter -Name "Ethernet" -NewName "Corp-LAN"
Get adapter statistics (bytes sent/received)
Get-NetAdapterStatistics | Select-Object Name, ReceivedBytes, SentBytes,
    @{N='ReceivedMB';E={[math]::Round($_.ReceivedBytes/1MB,2)}},
    @{N='SentMB';E={[math]::Round($_.SentBytes/1MB,2)}}
Reset network adapter (like unplugging)
Restart-NetAdapter -Name "Wi-Fi"
Get physical adapters only (no virtual)
Get-NetAdapter -Physical
Check for hardware problems
Get-NetAdapter | Select-Object Name, Status, MediaConnectionState,
    @{N='Problems';E={(Get-PnpDevice -InstanceId $_.PnPDeviceID).Problem}}

Network Diagnostics

Full network diagnostic report
Get-NetAdapter | Where-Object Status -eq 'Up' | ForEach-Object {
    $adapter = $_
    $ip = Get-NetIPAddress -InterfaceIndex $_.ifIndex -AddressFamily IPv4 -EA SilentlyContinue
    $gw = Get-NetRoute -InterfaceIndex $_.ifIndex -DestinationPrefix "0.0.0.0/0" -EA SilentlyContinue
    $dns = Get-DnsClientServerAddress -InterfaceIndex $_.ifIndex -AddressFamily IPv4 -EA SilentlyContinue

    [PSCustomObject]@{
        Adapter   = $adapter.Name
        Status    = $adapter.Status
        Speed     = $adapter.LinkSpeed
        MAC       = $adapter.MacAddress
        IPv4      = $ip.IPAddress
        Gateway   = $gw.NextHop
        DNS       = ($dns.ServerAddresses -join ", ")
    }
} | Format-List
Quick network status one-liner
Get-NetAdapter | Where-Object Status -eq 'Up' | ForEach-Object {
    $ip = (Get-NetIPAddress -InterfaceIndex $_.ifIndex -AddressFamily IPv4 -EA SilentlyContinue).IPAddress
    "$($_.Name): $ip [$($_.LinkSpeed)]"
}
Check all critical connectivity
$targets = @(
    @{Name="Gateway"; Host="10.50.1.1"},
    @{Name="DNS"; Host="10.50.1.50"},
    @{Name="Internet"; Host="8.8.8.8"},
    @{Name="Web"; Host="www.google.com"}
)

$targets | ForEach-Object {
    $result = Test-NetConnection -ComputerName $_.Host -WarningAction SilentlyContinue
    [PSCustomObject]@{
        Target = $_.Name
        Host   = $_.Host
        Ping   = if($result.PingSucceeded){"OK"}else{"FAIL"}
    }
} | Format-Table -AutoSize
Network connection quality test
$target = "10.50.1.1"
$results = 1..10 | ForEach-Object {
    $ping = Test-Connection -ComputerName $target -Count 1 -EA SilentlyContinue
    if ($ping) { $ping.ResponseTime } else { -1 }
}
$success = ($results | Where-Object { $_ -ge 0 }).Count
$avgLatency = ($results | Where-Object { $_ -ge 0 } | Measure-Object -Average).Average

Write-Host "Target: $target"
Write-Host "Success: $success/10"
Write-Host "Avg Latency: $([math]::Round($avgLatency,2)) ms"
Export network config for support
$report = @()
$report += "=== ADAPTERS ==="
$report += Get-NetAdapter | Format-Table -AutoSize | Out-String
$report += "`n=== IP CONFIG ==="
$report += Get-NetIPConfiguration | Out-String
$report += "`n=== ROUTES ==="
$report += Get-NetRoute -AddressFamily IPv4 | Format-Table -AutoSize | Out-String
$report += "`n=== DNS ==="
$report += Get-DnsClientServerAddress -AddressFamily IPv4 | Format-Table -AutoSize | Out-String
$report | Out-File "$env:TEMP\network-report.txt"
Write-Host "Report saved to $env:TEMP\network-report.txt"

IP Configuration

Full ipconfig /all equivalent
Get-NetIPConfiguration -Detailed
Quick IP info for active adapters
Get-NetIPAddress -AddressFamily IPv4 |
    Where-Object { $_.InterfaceAlias -notmatch 'Loopback' } |
    Select-Object InterfaceAlias, IPAddress, PrefixLength
Get default gateway
Get-NetRoute -DestinationPrefix 0.0.0.0/0 | Select-Object InterfaceAlias, NextHop
Get DNS servers
Get-DnsClientServerAddress -AddressFamily IPv4 |
    Where-Object ServerAddresses |
    Select-Object InterfaceAlias, ServerAddresses
Set static IP (Admin)
New-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress "10.50.1.100" -PrefixLength 24 -DefaultGateway "10.50.1.1"
Remove IP address
Remove-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress "10.50.1.100" -Confirm:$false
Set to DHCP (Admin)
Set-NetIPInterface -InterfaceAlias "Ethernet" -Dhcp Enabled
Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ResetServerAddresses
Set static DNS
Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses "10.50.1.50","10.50.1.51"
Clear DNS cache
Clear-DnsClientCache
View DNS cache
Get-DnsClientCache | Select-Object Entry, Data, TimeToLive
Release/renew DHCP (ipconfig /release /renew)
$adapter = Get-NetAdapter -Name "Ethernet"
$adapter | Set-NetIPInterface -Dhcp Enabled
Restart-NetAdapter -Name $adapter.Name
Test connectivity
Test-NetConnection -ComputerName "google.com"
Test connectivity with port check
Test-NetConnection -ComputerName "10.50.1.1" -Port 443 -InformationLevel Detailed
Trace route
Test-NetConnection -ComputerName "google.com" -TraceRoute | Select-Object -ExpandProperty TraceRoute
Check all established TCP connections with process names
Get-NetTCPConnection | Where-Object State -eq 'Established' |
    Select-Object LocalAddress, LocalPort, RemoteAddress, RemotePort,
        @{N='Process';E={(Get-Process -Id $_.OwningProcess).Name}} |
    Sort-Object LocalPort
Find what process is using a specific port
Get-NetTCPConnection -LocalPort 8080 |
    Select-Object LocalPort, @{N='Process';E={(Get-Process -Id $_.OwningProcess).ProcessName}}

Windows Firewall

Get firewall status
Get-NetFirewallProfile | Select-Object Name, Enabled, DefaultInboundAction, DefaultOutboundAction
Enable firewall for profile
Set-NetFirewallProfile -Profile Private -Enabled True
Set-NetFirewallProfile -Profile Public -Enabled True
List all firewall rules
Get-NetFirewallRule | Select-Object Name, DisplayName, Enabled, Direction, Action
Find rule by name
Get-NetFirewallRule -DisplayName "*Remote Desktop*"
Get enabled inbound rules with ports
Get-NetFirewallRule -Direction Inbound -Enabled True |
    Select-Object DisplayName, @{N='Port';E={($_ | Get-NetFirewallPortFilter).LocalPort}}
Create inbound allow rule
New-NetFirewallRule -DisplayName "Allow SSH" -Direction Inbound -Protocol TCP -LocalPort 22 -Action Allow
Create rule for specific program
New-NetFirewallRule -DisplayName "Allow MyApp" -Direction Inbound -Program "C:\Apps\myapp.exe" -Action Allow
Block outbound to specific IP
New-NetFirewallRule -DisplayName "Block BadIP" -Direction Outbound -RemoteAddress "1.2.3.4" -Action Block
Remove firewall rule
Remove-NetFirewallRule -DisplayName "Allow SSH"
Enable/disable rule
Enable-NetFirewallRule -DisplayName "Remote Desktop*"
Disable-NetFirewallRule -DisplayName "Remote Desktop*"
Export firewall rules
netsh advfirewall export "C:\Backup\firewall-rules.wfw"
Import firewall rules
netsh advfirewall import "C:\Backup\firewall-rules.wfw"
Get rules for specific port
Get-NetFirewallRule -Direction Inbound -Enabled True |
    Where-Object { ($_ | Get-NetFirewallPortFilter).LocalPort -eq 3389 } |
    Select-Object DisplayName, Enabled

LAN/Ethernet Management

List all wired (Ethernet) adapters
Get-NetAdapter -Physical | Where-Object { $_.MediaType -eq "802.3" -or $_.InterfaceDescription -match "Ethernet|LAN|Realtek|Intel.*Ethernet" }
Get Ethernet adapter status
Get-NetAdapter -Name "Ethernet*" | Select-Object Name, Status, LinkSpeed, MacAddress, MediaConnectionState
Check cable connection status
Get-NetAdapter -Physical | Select-Object Name, Status, MediaConnectionState,
    @{N='Cable';E={if($_.MediaConnectionState -eq 'Connected'){'Plugged'}else{'Unplugged'}}}
Get Ethernet connection profile (domain/private/public)
Get-NetConnectionProfile | Where-Object InterfaceAlias -match "Ethernet" |
    Select-Object InterfaceAlias, Name, NetworkCategory, IPv4Connectivity
Change network category for Ethernet
Set-NetConnectionProfile -InterfaceAlias "Ethernet" -NetworkCategory Private
# Options: Private, Public, DomainAuthenticated (auto-detected)
View wired 802.1X profiles
netsh lan show profiles
View specific wired profile
netsh lan show profiles interface="Ethernet"
Export wired 802.1X profile
netsh lan export profile folder="$env:TEMP" interface="Ethernet"
Import wired 802.1X profile
netsh lan add profile filename="$env:TEMP\Ethernet.xml" interface="Ethernet"
Enable/disable wired 802.1X autoconfig
# Enable
netsh lan set autoconfig enabled=yes interface="Ethernet"
# Disable
netsh lan set autoconfig enabled=no interface="Ethernet"
Ethernet adapter advanced properties
Get-NetAdapterAdvancedProperty -Name "Ethernet" |
    Select-Object DisplayName, DisplayValue, RegistryKeyword |
    Format-Table -AutoSize
Set Ethernet speed/duplex (common troubleshooting)
# View current setting
Get-NetAdapterAdvancedProperty -Name "Ethernet" -DisplayName "Speed & Duplex"

# Set to specific value (varies by driver)
Set-NetAdapterAdvancedProperty -Name "Ethernet" -DisplayName "Speed & Duplex" -DisplayValue "100 Mbps Full Duplex"
Enable/disable jumbo frames
Set-NetAdapterAdvancedProperty -Name "Ethernet" -DisplayName "Jumbo Packet" -DisplayValue "9014 Bytes"
Wake on LAN settings
Get-NetAdapterAdvancedProperty -Name "Ethernet" | Where-Object DisplayName -match "Wake"
Get Ethernet statistics
Get-NetAdapterStatistics -Name "Ethernet" | Select-Object Name,
    @{N='ReceivedGB';E={[math]::Round($_.ReceivedBytes/1GB,3)}},
    @{N='SentGB';E={[math]::Round($_.SentBytes/1GB,3)}},
    ReceivedUnicastPackets, SentUnicastPackets,
    ReceivedDiscards, OutboundDiscards, InboundErrors, OutboundErrors
Check for Ethernet errors
$stats = Get-NetAdapterStatistics -Name "Ethernet"
if ($stats.InboundErrors -gt 0 -or $stats.OutboundErrors -gt 0) {
    Write-Host "ERRORS DETECTED!" -ForegroundColor Red
    Write-Host "Inbound Errors:  $($stats.InboundErrors)"
    Write-Host "Outbound Errors: $($stats.OutboundErrors)"
    Write-Host "Check cable, switch port, or driver"
} else {
    Write-Host "No errors - connection healthy" -ForegroundColor Green
}
Reset Ethernet adapter (like unplugging cable)
Restart-NetAdapter -Name "Ethernet"
Disable/enable Ethernet
Disable-NetAdapter -Name "Ethernet" -Confirm:$false
Enable-NetAdapter -Name "Ethernet" -Confirm:$false
Force Ethernet over WiFi (set metric)
# Lower metric = higher priority
Set-NetIPInterface -InterfaceAlias "Ethernet" -InterfaceMetric 10
Set-NetIPInterface -InterfaceAlias "Wi-Fi" -InterfaceMetric 100
Compare LAN vs WiFi speed
Get-NetAdapter | Where-Object Status -eq 'Up' |
    Select-Object Name, InterfaceDescription,
        @{N='SpeedGbps';E={[math]::Round($_.LinkSpeed.Split()[0]/1000,2)}},
        Status | Format-Table -AutoSize

VPN

VPN Management

List all VPN connections
Get-VpnConnection | Select-Object Name, ServerAddress, TunnelType, AuthenticationMethod, ConnectionStatus
List VPN connections (including all users)
Get-VpnConnection -AllUserConnection
Connect to VPN
rasdial "VPN-Name"
# Or with credentials
rasdial "VPN-Name" username password
Connect using PowerShell cmdlet (Windows 8+)
# Note: Does not support passing credentials directly for security
Start-Process "rasphone" -ArgumentList "-d `"VPN-Name`""
Disconnect VPN
rasdial "VPN-Name" /disconnect
Disconnect all VPNs
rasdial | Select-String "Connected" | ForEach-Object {
    $vpnName = ($_ -split ":")[0].Trim()
    rasdial $vpnName /disconnect
}
Check VPN connection status
Get-VpnConnection | Where-Object ConnectionStatus -eq "Connected" | Select-Object Name, ServerAddress
Create IKEv2 VPN connection
Add-VpnConnection -Name "CorpVPN" `
    -ServerAddress "vpn.company.com" `
    -TunnelType IKEv2 `
    -AuthenticationMethod MachineCertificate `
    -EncryptionLevel Required `
    -RememberCredential
Create L2TP/IPSec VPN with pre-shared key
Add-VpnConnection -Name "SiteVPN" `
    -ServerAddress "vpn.site.com" `
    -TunnelType L2tp `
    -L2tpPsk "YourPreSharedKey" `
    -AuthenticationMethod Pap `
    -EncryptionLevel Optional `
    -Force
Create SSTP VPN
Add-VpnConnection -Name "SSTP-VPN" `
    -ServerAddress "vpn.company.com" `
    -TunnelType Sstp `
    -AuthenticationMethod MSChapv2 `
    -EncryptionLevel Required
Remove VPN connection
Remove-VpnConnection -Name "OldVPN" -Force
Set VPN to not be default gateway (split tunnel)
Set-VpnConnection -Name "CorpVPN" -SplitTunneling $true
Add routes for split tunnel VPN
Add-VpnConnectionRoute -ConnectionName "CorpVPN" -DestinationPrefix "10.0.0.0/8"
Add-VpnConnectionRoute -ConnectionName "CorpVPN" -DestinationPrefix "172.16.0.0/12"
Add-VpnConnectionRoute -ConnectionName "CorpVPN" -DestinationPrefix "192.168.0.0/16"
View VPN routes
Get-VpnConnectionRoute -ConnectionName "CorpVPN"
Set VPN DNS suffix
Set-VpnConnection -Name "CorpVPN" -DnsSuffix "corp.company.com"
VPN connection with EAP-TLS (certificate)
Add-VpnConnection -Name "CertVPN" `
    -ServerAddress "vpn.company.com" `
    -TunnelType IKEv2 `
    -AuthenticationMethod Eap `
    -EncryptionLevel Required
# Then configure EAP settings in rasphone.exe UI or via XML
Export VPN phonebook for backup
Copy-Item "$env:APPDATA\Microsoft\Network\Connections\Pbk\rasphone.pbk" "$env:TEMP\vpn-backup.pbk"
Troubleshoot VPN
# Recent VPN events
Get-WinEvent -LogName "Application" -MaxEvents 50 |
    Where-Object { $_.ProviderName -match "RasClient|Rasman" } |
    Select-Object TimeCreated, Message

# Check VPN adapter
Get-NetAdapter | Where-Object InterfaceDescription -match "VPN|WAN Miniport"

Proxy Configuration

Get current proxy settings
Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" |
    Select-Object ProxyEnable, ProxyServer, ProxyOverride, AutoConfigURL
Check proxy via netsh
netsh winhttp show proxy
Get system proxy (WinHTTP)
[System.Net.WebRequest]::GetSystemWebProxy()
Test if proxy is being used for URL
$proxy = [System.Net.WebRequest]::GetSystemWebProxy()
$proxy.GetProxy("https://www.google.com")
Set manual proxy (current user)
Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" -Name ProxyEnable -Value 1
Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" -Name ProxyServer -Value "proxy.company.com:8080"
Set proxy bypass list
Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" `
    -Name ProxyOverride -Value "*.local;10.*;192.168.*;172.16.*;<local>"
Disable proxy
Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" -Name ProxyEnable -Value 0
Set PAC file (auto-config)
Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings" `
    -Name AutoConfigURL -Value "http://wpad.company.com/proxy.pac"
Import WinHTTP proxy from IE settings (Admin)
netsh winhttp import proxy source=ie
Set WinHTTP proxy directly (Admin)
netsh winhttp set proxy proxy-server="proxy.company.com:8080" bypass-list="*.local;10.*"
Reset WinHTTP proxy (Admin)
netsh winhttp reset proxy
Set proxy for PowerShell session only
$proxy = New-Object System.Net.WebProxy("http://proxy.company.com:8080", $true)
[System.Net.WebRequest]::DefaultWebProxy = $proxy

# With credentials
$proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
Set proxy environment variables (current session)
$env:HTTP_PROXY = "http://proxy.company.com:8080"
$env:HTTPS_PROXY = "http://proxy.company.com:8080"
$env:NO_PROXY = "localhost,127.0.0.1,.local,10.*"
Test connectivity through proxy
Invoke-WebRequest -Uri "https://www.google.com" -Proxy "http://proxy.company.com:8080" -ProxyUseDefaultCredentials
Check if behind proxy (connectivity test)
$directTest = Test-NetConnection -ComputerName "www.google.com" -Port 443 -WarningAction SilentlyContinue
if (-not $directTest.TcpTestSucceeded) {
    Write-Host "Direct connection failed - likely behind proxy"
    try {
        $response = Invoke-WebRequest -Uri "https://www.google.com" -UseDefaultCredentials -TimeoutSec 10
        Write-Host "Proxy connection: OK (Status: $($response.StatusCode))"
    } catch {
        Write-Host "Proxy connection: FAILED"
    }
} else {
    Write-Host "Direct connection: OK"
}
Get proxy authentication status
$proxy = [System.Net.WebRequest]::GetSystemWebProxy()
$proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
try {
    $request = [System.Net.WebRequest]::Create("https://www.google.com")
    $request.Proxy = $proxy
    $response = $request.GetResponse()
    Write-Host "Proxy auth: OK"
    $response.Close()
} catch {
    Write-Host "Proxy auth: FAILED - $($_.Exception.Message)"
}

802.1X / EAP-TLS Authentication

Quick Status Check (typed daily)

WiFi interface status — SSID, BSSID, state
netsh wlan show int | Select-String -Pattern '^\s*(State|SSID|AP BSSID)'
Track specific interface by GUID
Get-NetAdapter | Where-Object InterfaceGuid -eq '{b4742d4f-b46c-4a67-9210-dcfb1586a69d}'
Inspect adapter object properties
Get-NetIPConfiguration | Get-Member
WLAN events for a specific interface GUID
Get-WinEvent -LogName Microsoft-Windows-WLAN-AutoConfig/Operational |
    Where-Object { $_.Message -match '055efc1d-2e42-46c2-8e30-bd1c3ce0b6b9' } |
    Select-Object TimeCreated, Id, LevelDisplayName, Message

Status and Service Management

Check 802.1X status on wired adapter
netsh lan show interfaces
Check 802.1X status on wireless
netsh wlan show interfaces | Select-String -Pattern "Authentication|State|SSID"
Enable 802.1X on wired adapter (Admin)
netsh lan set autoconfig enabled=yes interface="Ethernet"
Disable 802.1X on wired adapter
netsh lan set autoconfig enabled=no interface="Ethernet"
Export wired 802.1X profile
netsh lan export profile folder="$env:TEMP" interface="Ethernet"
Import wired 802.1X profile
netsh lan add profile filename="$env:TEMP\Ethernet.xml" interface="Ethernet"
View EAP configuration
netsh lan show profiles interface="Ethernet"
Check if DOT1X service is running
Get-Service -Name "dot3svc" | Select-Object Name, Status, StartType
Get-Service -Name "Wlansvc" | Select-Object Name, Status, StartType
Start 802.1X services
Start-Service -Name "dot3svc"   # Wired AutoConfig
Start-Service -Name "Wlansvc"   # WLAN AutoConfig
View certificate used for EAP-TLS
Get-ChildItem Cert:\CurrentUser\My | Where-Object {
    $_.EnhancedKeyUsageList.FriendlyName -contains "Client Authentication"
} | Select-Object Subject, Thumbprint, NotAfter
Check machine certificates (Admin)
Get-ChildItem Cert:\LocalMachine\My | Where-Object {
    $_.EnhancedKeyUsageList.FriendlyName -contains "Client Authentication"
} | Select-Object Subject, Thumbprint, NotAfter
View trusted root CAs for EAP
Get-ChildItem Cert:\LocalMachine\Root | Select-Object Subject, Thumbprint, NotAfter | Format-Table -AutoSize
Create WPA2-Enterprise WiFi profile (EAP-TLS)
$profileXml = @"
<?xml version="1.0"?>
<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1">
    <name>CorpWiFi-8021X</name>
    <SSIDConfig>
        <SSID><name>CorpWiFi</name></SSID>
    </SSIDConfig>
    <connectionType>ESS</connectionType>
    <connectionMode>auto</connectionMode>
    <MSM>
        <security>
            <authEncryption>
                <authentication>WPA2</authentication>
                <encryption>AES</encryption>
                <useOneX>true</useOneX>
            </authEncryption>
            <OneX xmlns="http://www.microsoft.com/networking/OneX/v1">
                <authMode>user</authMode>
                <EAPConfig>
                    <EapHostConfig xmlns="http://www.microsoft.com/provisioning/EapHostConfig">
                        <EapMethod>
                            <Type xmlns="http://www.microsoft.com/provisioning/EapCommon">13</Type>
                            <VendorId xmlns="http://www.microsoft.com/provisioning/EapCommon">0</VendorId>
                            <VendorType xmlns="http://www.microsoft.com/provisioning/EapCommon">0</VendorType>
                            <AuthorId xmlns="http://www.microsoft.com/provisioning/EapCommon">0</AuthorId>
                        </EapMethod>
                    </EapHostConfig>
                </EAPConfig>
            </OneX>
        </security>
    </MSM>
</WLANProfile>
"@
$profileXml | Out-File "$env:TEMP\corp-8021x.xml" -Encoding UTF8
netsh wlan add profile filename="$env:TEMP\corp-8021x.xml" user=all
Troubleshoot 802.1X authentication
# View recent 802.1X events
Get-WinEvent -LogName "Microsoft-Windows-WLAN-AutoConfig/Operational" -MaxEvents 20 |
    Where-Object { $_.Message -match "802.1X|EAP|authentication" } |
    Select-Object TimeCreated, Message

# Wired 802.1X events
Get-WinEvent -LogName "Microsoft-Windows-Wired-AutoConfig/Operational" -MaxEvents 20 |
    Select-Object TimeCreated, Message

Quick Reference

Daily commands (memorize these)
# === ADAPTERS ===
Get-NetAdapter | ft Name, Status, LinkSpeed           # What's connected?
Get-NetAdapter -Physical                               # Physical adapters only
Restart-NetAdapter -Name "Ethernet"                    # Restart (like unplug/replug)

# === IP CONFIG ===
Get-NetIPAddress -AddressFamily IPv4 | ? InterfaceAlias -notmatch Loopback | ft InterfaceAlias, IPAddress
Get-NetIPConfiguration -Detailed                       # Full ipconfig /all
Clear-DnsClientCache                                   # Flush DNS

# === WIFI ===
netsh wlan show networks                               # Available networks
netsh wlan show networks mode=bssid                    # With signal/security
netsh wlan show profiles                               # Saved networks
netsh wlan show profile name="X" key=clear             # Profile with password (Admin)
netsh wlan show interfaces                             # Current connection
netsh wlan connect name="NetworkName"                  # Connect
netsh wlan disconnect                                  # Disconnect
netsh wlan delete profile name="NetworkName"           # Forget network
netsh wlan export profile folder="C:\Temp" key=clear   # Export to XML
netsh wlan add profile filename="profile.xml"          # Import from XML

# === ETHERNET ===
netsh lan show interfaces                              # Wired 802.1X status
netsh lan show profiles                                # Wired profiles
Get-NetAdapterStatistics -Name "Ethernet"              # Traffic stats

# === CONNECTIVITY ===
Test-NetConnection 10.50.1.1                           # Ping test
Test-NetConnection google.com -Port 443                # Port check
Test-NetConnection google.com -TraceRoute              # Trace route

# === VPN ===
Get-VpnConnection                                      # List VPNs
rasdial "VPN-Name"                                     # Connect VPN
rasdial "VPN-Name" /disconnect                         # Disconnect VPN

# === PROXY ===
netsh winhttp show proxy                               # System proxy
One-liners to memorize
# All saved WiFi passwords (Admin)
(netsh wlan show profiles) -match "All User" -replace ".*:\s+","" | % { $n=$_; $p=(netsh wlan show profile name="$n" key=clear) -match "Key Content" -replace ".*:\s+",""; "$n`: $p" }

# Quick network status
Get-NetAdapter | ? Status -eq Up | % { "$($_.Name): $((Get-NetIPAddress -InterfaceIndex $_.ifIndex -AddressFamily IPv4 -EA 0).IPAddress) [$($_.LinkSpeed)]" }

# Am I on corporate network?
(Get-NetConnectionProfile).NetworkCategory -contains 'DomainAuthenticated'

# Export all WiFi profiles
netsh wlan export profile folder="$env:TEMP\wifi" key=clear

# Compare available vs saved WiFi
$s=(netsh wlan show profiles) -match "All User" -replace ".*:\s+",""; netsh wlan show networks | % { if($_ -match "SSID \d+ : (.+)"){ if($matches[1] -in $s){"[SAVED] $($matches[1])"}else{"[NEW] $($matches[1])"} } }
Troubleshooting sequence
# 1. Check adapter status
Get-NetAdapter | ft Name, Status, MediaConnectionState

# 2. Check IP config
Get-NetIPConfiguration | Select InterfaceAlias, IPv4Address, IPv4DefaultGateway, DNSServer

# 3. Test gateway
Test-NetConnection (Get-NetRoute -DestinationPrefix 0.0.0.0/0).NextHop

# 4. Test DNS
Resolve-DnsName google.com

# 5. Test internet
Test-NetConnection 8.8.8.8

# 6. Check for errors
Get-NetAdapterStatistics | ? { $_.InboundErrors -gt 0 -or $_.OutboundErrors -gt 0 }

WiFi Profile Inspection

PowerShell → jq Bridge Pattern

Pipe PowerShell output through ConvertTo-Json to unlock jq for structured querying on Windows. This gives you the same data manipulation power as Linux pipelines — without learning PowerShell’s native object model.

Dump full profile as JSON
netsh wlan show profile name=CHLA-Remote |
  ConvertTo-Json | jq '.'                                    (1)
1 ConvertTo-Json wraps each line of netsh output as a JSON string array element — jq can then filter, select, and transform
Boolean assertion — verify enterprise WiFi configuration
netsh wlan show profile name=CHLA-Remote |
  ConvertTo-Json |
  jq -e '
    map(select(test("WPA2-Enterprise|TEAP|802.1X"))) |
    length == 3
  '                                                          (1)
1 -e flag sets exit code based on truthiness — use in if blocks or CI/CD gates. Returns 0 (true) if all three enterprise markers are present
Key-value extraction — parse netsh into structured objects
netsh wlan show profile name=CHLA-Remote |
  ConvertTo-Json |
  jq '
    .[] |
    select(test(" : ")) |
    split(" : ") |
    {
      key: (.[0] | gsub("\\s+$";"")),
      value: (.[1] | gsub("^\\s+";""))
    }
  '                                                          (1)
1 Splits netsh key-value lines on ` : ` delimiter, trims whitespace with gsub, produces clean JSON objects for each setting
Pipe through bat for paginated syntax highlighting
netsh wlan show profile name=CHLA-Remote |
  ConvertTo-Json | jq '.' | bat --paging=always              (1)
1 bat provides syntax highlighting and pagination — useful for long profiles

Network Adapter Diagnostics

Quick adapter status check
Get-NetAdapter -Name "Wi-Fi"                                 (1)
1 Fast check — returns Status, LinkSpeed, MacAddress for a single adapter
PnP device problem detection
Get-NetAdapter |
  Select-Object Name, Status, MediaConnectionState,
    @{N='Problems';E={                                       (1)
      (Get-PnpDevice -InstanceId $_.PnPDeviceID).Problem
    }}
1 Calculated property joins PnP device data — exposes hardware problems (driver issues, disabled devices) that Get-NetAdapter alone hides
Detailed view of active adapters — custom PSObject
Get-NetAdapter | Where-Object Status -eq 'Up' |
  ForEach-Object {
    $ip = Get-NetIPAddress `
      -InterfaceIndex $_.ifIndex `
      -AddressFamily IPv4 `
      -ErrorAction SilentlyContinue                          (1)
    [PSCustomObject]@{
      Adapter  = $_.Name
      Status   = $_.Status
      Speed    = $_.LinkSpeed
      MAC      = $_.MacAddress
      IPv4     = $ip.IPAddress
      Prefix   = $ip.PrefixLength
    }
  } | Format-Table                                           (2)
1 SilentlyContinue prevents errors for adapters without IPv4 (e.g., VPN tunnels, Bluetooth)
2 Format-Table outputs aligned columns — swap for ConvertTo-Json | jq '.' when piping to other tools
Raw adapter dump as JSON
Get-NetAdapter | ConvertTo-Json | jq '.'                     (1)
1 Full adapter properties — over 60 fields including driver version, NIC features, offload settings

WLAN Discovery

Full BSSID enumeration — all visible access points
netsh wlan show networks mode=bssid                          (1)
1 Shows every AP with BSSID (MAC), signal strength, channel, encryption — essential for wireless site surveys and rogue AP detection
Filter for specific SSIDs
netsh wlan show networks | Select-String CHLA-Remote         (1)
netsh wlan show networks | Select-String Domus-IoT           (2)
1 Quick check — is the enterprise SSID visible from this location?
2 Verify home IoT network broadcast reach

Service Enumeration via jq

Count running services
Get-Service |
  ConvertTo-Json |
  jq '[.[] | select(.Status == "Running") | .Name] | length' (1)
1 PowerShell → JSON → jq pipeline. The select filters for running services, wraps names in array, length counts. Baseline your service count — deviations indicate drift or compromise