Skip to content

Instantly share code, notes, and snippets.

@minanagehsalalma
Created July 21, 2026 08:56
Show Gist options
  • Select an option

  • Save minanagehsalalma/8c35f97d9bd0847d9581762852a49d83 to your computer and use it in GitHub Desktop.

Select an option

Save minanagehsalalma/8c35f97d9bd0847d9581762852a49d83 to your computer and use it in GitHub Desktop.
Restore a Missing Wi-Fi Tile in Windows 11 Quick Settings

Restore a Missing Wi-Fi Tile in Windows 11 Quick Settings

This Gist repairs a Windows 11 Quick Settings panel where the Wi-Fi tile or network list is missing even though the wireless adapter is installed and may already be connected.

The important detail on recent Windows 11 builds is that Quick Settings can be hosted by ShellHost.exe. Restarting only the older ShellExperienceHost.exe may therefore have no effect.

What the script does

  • Creates timestamped registry backups in your Documents folder.
  • starts Network Location Awareness if needed and restarts WLAN AutoConfig;
  • checks Wi-Fi enumeration without printing nearby network names;
  • preserves the existing Quick Settings layout while adding or moving Wi-Fi to the first position;
  • refreshes both ShellHost.exe and ShellExperienceHost.exe so the repaired layout is loaded;
  • leaves saved Wi-Fi profiles and passwords untouched.

Two more invasive recovery steps are available only through explicit switches:

  • -CycleAdapterIfNeeded briefly disables and re-enables the physical Wi-Fi adapter if network enumeration still fails.
  • -RepairShellPackages re-registers the Windows shell packages used by Quick Settings.
  • -UseNativeTaskbar keeps ExplorerPatcher installed but switches it to the native Windows taskbar if legacy taskbar routing is blocking Quick Settings.

Run it

  1. Save repair-wifi-quick-settings.ps1 from this Gist.
  2. Open Windows PowerShell as Administrator.
  3. Change to the folder containing the script.
  4. Run:
Set-ExecutionPolicy -Scope Process Bypass
.\repair-wifi-quick-settings.ps1

When it finishes, press Win+A. The Wi-Fi tile should be in the first position; select its arrow to open the network list.

If the first run does not restore network enumeration, try:

.\repair-wifi-quick-settings.ps1 -CycleAdapterIfNeeded

For shell-package corruption, use the optional escalation:

.\repair-wifi-quick-settings.ps1 -CycleAdapterIfNeeded -RepairShellPackages

If ExplorerPatcher is installed and the flyout still does not open:

.\repair-wifi-quick-settings.ps1 -UseNativeTaskbar

This last option does not uninstall ExplorerPatcher.

If netsh wlan show networks says Access is denied

Windows 11 24H2 and later can restrict Wi-Fi network scanning when precise location access is disabled. Open Settings > Privacy & security > Location and verify that Location services and desktop-app location access are enabled, then run the script again.

Microsoft documents this behavior in Wi-Fi access and location changes.

Roll back

Each run creates a folder named similar to WiFi-Quick-Settings-Backup-20260721-110300 in Documents. To restore the old Quick Settings layout, double-click QuickActions.reg in that folder and sign out and back in.

If -UseNativeTaskbar was used, ExplorerPatcher.reg is also created when an ExplorerPatcher configuration was present. Import it to restore those settings.

Privacy

The script does not print SSIDs, BSSIDs, MAC addresses, computer names, user names, or saved Wi-Fi profiles. This write-up contains no machine-specific paths or device identifiers.

@minanagehsalalma

Copy link
Copy Markdown
Author
#Requires -Version 5.1
#Requires -RunAsAdministrator

[CmdletBinding()]
param(
    [switch]$CycleAdapterIfNeeded,
    [switch]$RepairShellPackages,
    [switch]$UseNativeTaskbar,
    [string]$AdapterName
)

$ErrorActionPreference = 'Stop'

function Write-Step {
    param([Parameter(Mandatory)][string]$Message)
    Write-Host "`n==> $Message" -ForegroundColor Cyan
}

function Export-RegistryKeyIfPresent {
    param(
        [Parameter(Mandatory)][string]$ProviderPath,
        [Parameter(Mandatory)][string]$RegistryPath,
        [Parameter(Mandatory)][string]$Destination
    )

    if (Test-Path -LiteralPath $ProviderPath) {
        & reg.exe export $RegistryPath $Destination /y | Out-Null
        if ($LASTEXITCODE -ne 0) {
            throw "Could not back up registry key: $RegistryPath"
        }
    }
}

function Test-WlanEnumeration {
    $scanText = (& netsh.exe wlan show networks 2>&1 | Out-String)
    $scanExitCode = $LASTEXITCODE

    if ($scanExitCode -ne 0) {
        return $false
    }

    if ($scanText -match '(?i)access is denied|error\s+5|location permission') {
        return $false
    }

    return $true
}

function Restart-WlanServices {
    $nla = Get-Service -Name 'NlaSvc' -ErrorAction SilentlyContinue
    if ($nla -and $nla.Status -ne 'Running') {
        Start-Service -Name 'NlaSvc'
    }

    Restart-Service -Name 'WlanSvc' -Force
    Start-Sleep -Seconds 2
}

function Resolve-WirelessAdapter {
    if ($AdapterName) {
        return Get-NetAdapter -Name $AdapterName -Physical -ErrorAction Stop
    }

    $candidates = @(
        Get-NetAdapter -Physical -ErrorAction Stop |
            Where-Object {
                $_.Name -match '(?i)wi-?fi|wireless|wlan' -or
                $_.InterfaceDescription -match '(?i)wireless|wi-?fi|wlan|802\.11'
            }
    )

    if ($candidates.Count -eq 0) {
        throw 'No physical wireless adapter was detected.'
    }

    if ($candidates.Count -gt 1) {
        throw 'More than one wireless adapter was detected. Rerun with -AdapterName and the interface name shown by Get-NetAdapter.'
    }

    return $candidates[0]
}

function Set-WifiQuickActionFirst {
    $quickActionsKey = 'HKCU:\Control Panel\Quick Actions\Control Center'
    $layoutName = 'UserLayoutPaginated'
    $wifiActionId = 'Microsoft.QuickAction.WiFi'
    $layout = $null

    New-Item -Path $quickActionsKey -Force | Out-Null

    try {
        $existingJson = Get-ItemPropertyValue -LiteralPath $quickActionsKey -Name $layoutName -ErrorAction Stop
        if ($existingJson) {
            $layout = $existingJson | ConvertFrom-Json -ErrorAction Stop
        }
    }
    catch {
        $layout = $null
    }

    if ($layout -and $layout.Toggles) {
        $preservedToggles = @(
            $layout.Toggles |
                Where-Object { $_.FriendlyName -ne $wifiActionId }
        )
        $layout.Toggles = @(
            [pscustomobject]@{ FriendlyName = $wifiActionId }
        ) + $preservedToggles
    }
    else {
        $layout = [pscustomobject]@{
            Toggles = @(
                [pscustomobject]@{ FriendlyName = 'Microsoft.QuickAction.WiFi' }
                [pscustomobject]@{ FriendlyName = 'Microsoft.QuickAction.Bluetooth' }
                [pscustomobject]@{ FriendlyName = 'Microsoft.QuickAction.AirplaneMode' }
                [pscustomobject]@{ FriendlyName = 'Microsoft.QuickAction.Accessibility' }
                [pscustomobject]@{ FriendlyName = 'Microsoft.QuickAction.EnergySaverAcOnly' }
                [pscustomobject]@{ FriendlyName = 'Microsoft.QuickAction.LiveCaptions' }
                [pscustomobject]@{ FriendlyName = 'Microsoft.QuickAction.BlueLightReduction' }
            )
            Sliders = @(
                [pscustomobject]@{ FriendlyName = 'Microsoft.QuickAction.Brightness' }
                [pscustomobject]@{ FriendlyName = 'Microsoft.QuickAction.VolumeNoTimer' }
            )
        }
    }

    $updatedJson = $layout | ConvertTo-Json -Depth 10 -Compress
    New-ItemProperty -LiteralPath $quickActionsKey -Name $layoutName -PropertyType String -Value $updatedJson -Force | Out-Null
}

function Repair-ShellPackageRegistrations {
    $packageNames = @(
        'Microsoft.Windows.ShellExperienceHost',
        'MicrosoftWindows.Client.CBS'
    )

    foreach ($packageName in $packageNames) {
        $packages = @(Get-AppxPackage -Name $packageName -ErrorAction SilentlyContinue)
        foreach ($package in $packages) {
            $manifest = Join-Path -Path $package.InstallLocation -ChildPath 'AppxManifest.xml'
            if (Test-Path -LiteralPath $manifest) {
                Add-AppxPackage -DisableDevelopmentMode -Register $manifest
            }
        }
    }
}

function Refresh-QuickSettingsHost {
    Get-Process -Name 'ShellHost', 'ShellExperienceHost' -ErrorAction SilentlyContinue |
        Stop-Process -Force

    if ($UseNativeTaskbar) {
        Get-Process -Name 'explorer' -ErrorAction SilentlyContinue | Stop-Process -Force
        Start-Sleep -Seconds 2
        & "$env:WINDIR\explorer.exe"
    }
}

$documentsFolder = [Environment]::GetFolderPath('MyDocuments')
if ([string]::IsNullOrWhiteSpace($documentsFolder)) {
    $documentsFolder = $env:TEMP
}

$timestamp = Get-Date -Format 'yyyyMMdd-HHmmss'
$backupFolder = Join-Path -Path $documentsFolder -ChildPath "WiFi-Quick-Settings-Backup-$timestamp"
New-Item -ItemType Directory -Path $backupFolder -Force | Out-Null

Write-Step 'Backing up the current per-user configuration'
Export-RegistryKeyIfPresent `
    -ProviderPath 'HKCU:\Control Panel\Quick Actions\Control Center' `
    -RegistryPath 'HKCU\Control Panel\Quick Actions\Control Center' `
    -Destination (Join-Path $backupFolder 'QuickActions.reg')
Export-RegistryKeyIfPresent `
    -ProviderPath 'HKCU:\Software\ExplorerPatcher' `
    -RegistryPath 'HKCU\Software\ExplorerPatcher' `
    -Destination (Join-Path $backupFolder 'ExplorerPatcher.reg')
Write-Host "Backup folder: $backupFolder"

Write-Step 'Restarting Windows Wi-Fi services'
Restart-WlanServices
$wlanWorks = Test-WlanEnumeration

if (-not $wlanWorks -and $CycleAdapterIfNeeded) {
    Write-Step 'Cycling the physical wireless adapter'
    $wirelessAdapter = Resolve-WirelessAdapter
    Disable-NetAdapter -Name $wirelessAdapter.Name -Confirm:$false
    Start-Sleep -Seconds 2
    Enable-NetAdapter -Name $wirelessAdapter.Name -Confirm:$false
    Start-Sleep -Seconds 5
    Restart-WlanServices
    $wlanWorks = Test-WlanEnumeration
}

if ($wlanWorks) {
    Write-Host 'Wi-Fi network enumeration succeeded. Network names were not displayed.' -ForegroundColor Green
}
else {
    Write-Warning 'Wi-Fi enumeration is still unavailable. Check Settings > Privacy & security > Location, then rerun with -CycleAdapterIfNeeded if needed.'
}

Write-Step 'Restoring the Wi-Fi Quick Settings action'
Set-WifiQuickActionFirst

if ($RepairShellPackages) {
    Write-Step 'Re-registering Windows shell packages'
    Repair-ShellPackageRegistrations
}

if ($UseNativeTaskbar) {
    $explorerPatcherKey = 'HKCU:\Software\ExplorerPatcher'
    if (Test-Path -LiteralPath $explorerPatcherKey) {
        Write-Step 'Switching ExplorerPatcher to the native taskbar'
        New-ItemProperty -LiteralPath $explorerPatcherKey -Name 'OldTaskbar' -PropertyType DWord -Value 0 -Force | Out-Null
        New-ItemProperty -LiteralPath $explorerPatcherKey -Name 'HideControlCenterButton' -PropertyType DWord -Value 0 -Force | Out-Null
    }
    else {
        Write-Warning 'ExplorerPatcher settings were not found; no taskbar setting was changed.'
    }
}

Write-Step 'Refreshing the Quick Settings host'
Refresh-QuickSettingsHost

Write-Host "`nDone. Press Win+A, then select the arrow on the Wi-Fi tile." -ForegroundColor Green
Write-Host 'If the panel was already open, close it and press Win+A again.'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment