86°F Knoxville
Mon–Fri 9–5 ETAnswered by a human
Automation · RESOLVED

Lost Wi-Fi Passwords: Bulk Recovery from Existing Devices

Office move, IT person quit, no documentation. 23 SSIDs saved on machines but nobody knew the passwords. Extracted all credentials in 12 minutes.

Incident

New client emergency. They were moving offices in 48 hours. Their previous IT person had quit abruptly about a month earlier and left zero documentation behind. Nobody knew the Wi-Fi passwords for the guest network, the warehouse APs, or the conference room networks — 23 different SSIDs saved across various laptops, all passwords unknown. Factory resetting the access points would wipe every config and VLAN mapping along with them, and the move couldn't wait two weeks for a rebuild. They needed the credentials now.

The knowledge gap

Classic small-business IT scenario:

  • IT documentation: none (previous admin kept it all in his head)
  • password manager: existed, but nobody else had access
  • AP admin access: unknown credentials
  • ISP router login: default was changed, unknown

Single point of failure IT. When that person leaves under bad terms, all institutional knowledge leaves with them. But Windows stores every Wi-Fi password the machine has ever connected to — if you know where to look and you have the right context to decrypt it.

How Windows stores wi-fi

Credential storage is not a secret, just an obscured one:

  • profiles live under HKLM\SOFTWARE\Microsoft\Wlansvc
  • keys are encrypted with machine DPAPI
  • netsh decrypts them when run as SYSTEM or a local admin

The command netsh wlan show profile name="SSID" key=clear reveals the plaintext password — but only with admin privileges. Running via RMM as SYSTEM gives us access to every saved network on every managed device, with no user interaction.

Solution

Deploy via RMM to extract every saved Wi-Fi credential from every endpoint in the fleet. Cross-reference the per-machine results to build a complete list — employees' laptops had some SSIDs the warehouse terminals didn't, and vice versa.

wifi_passwords_show.ps1View on GitHub →
$ErrorActionPreference = 'Stop'
<#
██╗     ██╗███╗   ███╗███████╗██╗  ██╗ █████╗ ██╗    ██╗██╗  ██╗
██║     ██║████╗ ████║██╔════╝██║  ██║██╔══██╗██║    ██║██║ ██╔╝
██║     ██║██╔████╔██║█████╗  ███████║███████║██║ █╗ ██║█████╔╝
██║     ██║██║╚██╔╝██║██╔══╝  ██╔══██║██╔══██║██║███╗██║██╔═██╗
███████╗██║██║ ╚═╝ ██║███████╗██║  ██║██║  ██║╚███╔███╔╝██║  ██╗
╚══════╝╚═╝╚═╝     ╚═╝╚══════╝╚═╝  ╚═╝╚═╝  ╚═╝ ╚══╝╚══╝ ╚═╝  ╚═╝

================================================================================
 SCRIPT  : Show Saved Wi-Fi Passwords v1.0.2
 AUTHOR  : Limehawk.io
 DATE      : January 2026
 FILE    : wifi_passwords_show.ps1
 DESCRIPTION : Retrieves and displays all saved Wi-Fi network passwords
 USAGE   : .\wifi_passwords_show.ps1
================================================================================
 README
--------------------------------------------------------------------------------
 PURPOSE:
    Retrieves and displays all saved Wi-Fi network profiles and their passwords
    stored on the Windows system. Useful for recovering forgotten passwords or
    auditing saved wireless credentials.

REQUIRED INPUTS:
    None

BEHAVIOR:
    1. Queries all saved wireless network profiles
    2. Retrieves the password (key content) for each profile
    3. Displays results in a formatted table

PREREQUISITES:
    - Windows 10/11 or Windows Server
    - Administrator privileges (for key retrieval)
    - Wireless adapter present (or previously present)

SECURITY NOTES:
    - This script displays sensitive credential information
    - Run only on systems you are authorized to audit
    - Passwords are retrieved from Windows credential store

EXIT CODES:
    0 = Success
    1 = Failure

EXAMPLE RUN:
    [RUN] RETRIEVING WI-FI PROFILES
    ==============================================================

    SSID_NAME          WIFI_PASSWORD
    ---------          -------------
    HomeNetwork        MySecurePass123
    OfficeWiFi         Corp0r@teKey!
    GuestNetwork       guest2024

    [OK] FINAL STATUS
    ==============================================================
    Result : 3 network(s) found

    [OK] SCRIPT COMPLETED
    ==============================================================

--------------------------------------------------------------------------------
 CHANGELOG
--------------------------------------------------------------------------------
 2026-01-19 v1.0.2 Updated to two-line ASCII console output style
 2025-12-23 v1.0.1 Updated to Limehawk Script Framework
 2024-12-01 v1.0.0 Initial release - migrated from SuperOps
================================================================================
#>
Set-StrictMode -Version Latest

# ============================================================================
# RETRIEVE WI-FI PROFILES
# ============================================================================
Write-Host ""
Write-Host "[RUN] RETRIEVING WI-FI PROFILES"
Write-Host "=============================================================="

try {
    $profiles = (netsh wlan show profiles) | Select-String "\:(.+)$" | ForEach-Object {
        $_.Matches.Groups[1].Value.Trim()
    }

    if (-not $profiles -or $profiles.Count -eq 0) {
        Write-Host "No saved Wi-Fi profiles found"
        Write-Host ""
        Write-Host "[OK] FINAL STATUS"
        Write-Host "=============================================================="
        Write-Host "Result : No networks found"
        exit 0
    }

    $results = @()

    foreach ($profile in $profiles) {
        $password = ""

        try {
            $keyContent = (netsh wlan show profile name="$profile" key=clear) |
                Select-String "Key Content\W+\:(.+)$"

            if ($keyContent) {
                $password = $keyContent.Matches.Groups[1].Value.Trim()
            }
        }
        catch {
            $password = "(unable to retrieve)"
        }

        $results += [PSCustomObject]@{
            SSID_NAME     = $profile
            WIFI_PASSWORD = if ($password) { $password } else { "(no password)" }
        }
    }

    Write-Host ""
    $results | Format-Table -AutoSize
}
catch {
    Write-Host ""
    Write-Host "[ERROR] RETRIEVAL FAILED"
    Write-Host "=============================================================="
    Write-Host "Failed to retrieve Wi-Fi profiles"
    Write-Host "Error : $($_.Exception.Message)"
    exit 1
}

# ============================================================================
# FINAL STATUS
# ============================================================================
Write-Host ""
Write-Host "[OK] FINAL STATUS"
Write-Host "=============================================================="
Write-Host "Result : $($results.Count) network(s) found"

Write-Host ""
Write-Host "[OK] SCRIPT COMPLETED"
Write-Host "=============================================================="

exit 0

Security note

This script retrieves sensitive credentials. We only run it on systems we're authorized to manage, for legitimate recovery purposes. Output is captured in RMM logs (encrypted at rest) and shared only with authorized personnel at the client. After documentation is complete we recommend rotating every recovered password and storing the new ones in a shared password manager — the whole point is to never be in this situation again.

Outcome

Script ran across 34 machines in parallel. Some machines had passwords others didn't — the employee laptops knew the office and guest networks, the warehouse terminals knew the warehouse SSIDs, the conference room PCs knew a couple of one-off SSIDs nobody else saw. Consolidating the results gave us every network credential the environment used. The move went ahead on schedule.

endpoints scanned: 34 workstations unique SSIDs found: 23 networks passwords recovered: 23 of 23 time to complete: 12 minutes

After the move we built proper documentation in the client's new shared password manager, rotated the critical credentials, and set up a bus-factor-of-one warning system so this wouldn't happen to them again.

Key takeaways