Skip to content

Instantly share code, notes, and snippets.

@ergosteur
Created December 10, 2025 21:51
Show Gist options
  • Select an option

  • Save ergosteur/cf1365d3a3c321d603d30de909c7ad71 to your computer and use it in GitHub Desktop.

Select an option

Save ergosteur/cf1365d3a3c321d603d30de909c7ad71 to your computer and use it in GitHub Desktop.
PowerShell script that analyzes Windows Wi-Fi profiles to extract SSID, Security, and Certificate Trust details.
<#
.SYNOPSIS
Analyzes Windows Wi-Fi profiles to extract SSID, Security, and Certificate Trust details.
.DESCRIPTION
This tool provides a detailed analysis of Wi-Fi connection profiles, specifically focusing on
Enterprise (802.1X) security settings. It extracts the Trusted Root CA Thumbprint, Server
Name constraints, and validates if the required certificates are present in the local machine store.
It operates in three modes:
1. Interactive Mode: select from a menu of saved profiles.
2. Direct Mode: Analyze a specific profile by name.
3. File Mode: Analyze an existing XML profile file.
.EXAMPLE
.\Get-Wifi-Profile-Analyzer.ps1 -Interactive
Launches a menu to select a Wi-Fi profile.
.EXAMPLE
.\Get-Wifi-Profile-Analyzer.ps1 -ProfileName "ContosoWLAN"
Analyzes the "ContosoWLAN" profile directly.
#>
[CmdletBinding(DefaultParameterSetName="ShowHelp")]
param(
# Mode 1: Interactive Menu
[Parameter(ParameterSetName="Interactive", Mandatory=$true)]
[switch]$Interactive,
# Mode 2: Direct System Profile
[Parameter(ParameterSetName="ByName", Mandatory=$true, Position=0)]
[string]$ProfileName,
# Mode 3: Analyze an existing XML file
[Parameter(ParameterSetName="ByFile", Mandatory=$true, Position=0)]
[Alias("ProfilePath")]
[string]$Path
)
# --- HELPER 1: CORE XML ANALYSIS ---
function Analyze-WifiProfileXml {
param ([xml]$XmlProfile, [string]$SourceName)
Write-Host "==================================================" -ForegroundColor Cyan
Write-Host " WI-FI PROFILE ANALYZER: $($XmlProfile.WLANProfile.name)" -ForegroundColor Cyan
Write-Host "==================================================" -ForegroundColor Cyan
Write-Host "Source: $SourceName`n"
# --- PART 1: GENERAL SETTINGS ---
Write-Host "--- General Wi-Fi Settings ---" -ForegroundColor Yellow
# Extract standard fields (safe navigation)
$SSIDName = $XmlProfile.WLANProfile.SSIDConfig.SSID.name
$ConnType = $XmlProfile.WLANProfile.connectionType
$ConnMode = $XmlProfile.WLANProfile.connectionMode
$AutoSwitch = $XmlProfile.WLANProfile.autoSwitch
Write-Host "SSID Name: $SSIDName"
Write-Host "Network Type: $ConnType"
Write-Host "Connection Mode: $ConnMode"
Write-Host "Auto-Connect: $AutoSwitch"
# --- PART 2: SECURITY BASICS ---
Write-Host "`n--- Security Basics ---" -ForegroundColor Yellow
$AuthAlgo = $XmlProfile.WLANProfile.MSM.security.authEncryption.authentication
$Cipher = $XmlProfile.WLANProfile.MSM.security.authEncryption.encryption
$UseOneX = $XmlProfile.WLANProfile.MSM.security.authEncryption.useOneX
$AuthMode = $XmlProfile.WLANProfile.MSM.security.OneX.authMode
Write-Host "Authentication: $AuthAlgo"
Write-Host "Encryption: $Cipher"
Write-Host "802.1X Enabled: $UseOneX"
if ($AuthMode) { Write-Host "Auth Mode: $AuthMode" }
# --- PART 3: ADVANCED TRUST SETTINGS ---
if ($UseOneX -eq "true") {
Write-Host "`n--- Certificate Trust & EAP Settings ---" -ForegroundColor Yellow
# 1. Trusted Root CA Hash
$RootCANodes = $XmlProfile.GetElementsByTagName("TrustedRootCA")
if ($RootCANodes.Count -gt 0) {
$RawHash = $RootCANodes[0].InnerText
$CleanHash = $RawHash -replace '\s',''
Write-Host "Trusted Root CA (Thumbprint):"
Write-Host " $CleanHash" -ForegroundColor Green
# --- LOOKUP CERTIFICATE ---
Write-Host " ...Checking local store..." -NoNewline
$CertPaths = @("Cert:\LocalMachine\Root", "Cert:\LocalMachine\CA", "Cert:\LocalMachine\My", "Cert:\CurrentUser\Root")
$CertFound = $null
foreach ($CertPath in $CertPaths) {
if (Test-Path $CertPath) {
$CertFound = Get-ChildItem -Path $CertPath -ErrorAction SilentlyContinue | Where-Object { $_.Thumbprint -eq $CleanHash } | Select-Object -First 1
if ($CertFound) { break }
}
}
if ($CertFound) {
Write-Host " FOUND in $($CertFound.PSParentPath.Split('\')[-1])" -ForegroundColor Green
Write-Host " Subject: $($CertFound.Subject)"
Write-Host " Issuer: $($CertFound.Issuer)"
Write-Host " Expires: $($CertFound.NotAfter)"
if ($CertFound.NotAfter -lt (Get-Date)) {
Write-Host " STATUS: ❌ EXPIRED" -ForegroundColor Red
} else {
Write-Host " STATUS: ✅ Valid" -ForegroundColor Green
}
} else {
Write-Host " NOT FOUND on this machine." -ForegroundColor Red
Write-Host " (Profile trusts this hash, but cert is missing)"
}
} else {
Write-Host "Trusted Root CA: Not explicitly defined (May use system defaults)" -ForegroundColor DarkGray
}
# 2. Server Name Constraints
$ServerNameNodes = $XmlProfile.GetElementsByTagName("ServerNames")
if ($ServerNameNodes.Count -gt 0) {
Write-Host "`nServer Name Constraint:"
Write-Host " $($ServerNameNodes[0].InnerText)" -ForegroundColor Green
} else {
Write-Host "`nServer Name Constraint: None" -ForegroundColor DarkGray
}
# 3. Validation Flags
$ValidationNodes = $XmlProfile.GetElementsByTagName("PerformServerValidation")
if ($ValidationNodes.Count -gt 0) {
Write-Host "`nPerform Server Validation:"
Write-Host " $($ValidationNodes[0].InnerText)"
}
} else {
Write-Host "`n(No EAP/Certificate settings to analyze for non-Enterprise networks)"
}
Write-Host "`n==================================================" -ForegroundColor Cyan
}
# --- HELPER 2: EXPORT AND PROCESS SYSTEM PROFILE ---
function Process-SystemProfile {
param ([string]$Name)
# Create temp folder
$TempDir = Join-Path $env:TEMP "WifiProfileExport_$(Get-Random)"
New-Item -ItemType Directory -Path $TempDir -Force | Out-Null
try {
# Export profile
$ExportResult = netsh wlan export profile name="$Name" folder="$TempDir" | Out-String
$ExportedFile = Get-ChildItem -Path $TempDir -Filter "*.xml" | Select-Object -First 1
if ($ExportedFile) {
[xml]$XmlData = Get-Content -Path $ExportedFile.FullName -Raw
Analyze-WifiProfileXml -XmlProfile $XmlData -SourceName "System Profile (Live Export)"
} else {
Write-Error "Failed to export profile '$Name'. Verify the name and ensure you have Administrator rights (required for GPO profiles)."
}
}
finally {
# Cleanup
Remove-Item -Path $TempDir -Recurse -Force -ErrorAction SilentlyContinue
}
}
# --- MAIN LOGIC ---
if ($PSCmdlet.ParameterSetName -eq "ByFile") {
# MODE A: Parsing an existing file
if (-not (Test-Path $Path)) {
Write-Error "File not found: $Path"
return
}
[xml]$XmlData = Get-Content -Path $Path -Raw
Analyze-WifiProfileXml -XmlProfile $XmlData -SourceName "XML File ($Path)"
} elseif ($PSCmdlet.ParameterSetName -eq "ByName") {
# MODE B: Exporting Specific System Profile
Process-SystemProfile -Name $ProfileName
} elseif ($PSCmdlet.ParameterSetName -eq "Interactive") {
# MODE C: Interactive Menu
Write-Host "`nScanning system for Wi-Fi profiles..." -ForegroundColor Cyan
$NetshOutput = netsh wlan show profiles
$ProfileList = @()
# 1. Capture Standard Profiles (Format: " All User Profile : Name")
$StandardProfiles = $NetshOutput | Select-String -Pattern "All User Profile\s*:\s*(.+)$"
if ($StandardProfiles) {
foreach ($item in $StandardProfiles) {
$ProfileList += $item.Matches.Groups[1].Value.Trim()
}
}
# 2. Capture GPO/Other Profiles (Format: " Name" - just indented, no key:value)
$GpoCandidates = $NetshOutput | Where-Object {
$_ -match "^\s{2,}" -and # Must be indented
$_ -notmatch ":" -and # No colon (avoids 'Key : Value' lines)
$_ -notmatch "-{3,}" -and # No separator lines (-----)
$_ -notmatch "<None>" -and # No empty indicators
$_ -notmatch "Profiles on" -and
$_ -notmatch "Group policy" -and
$_ -notmatch "User profiles"
}
if ($GpoCandidates) {
foreach ($line in $GpoCandidates) {
$cleanName = $line.Trim()
if (-not [string]::IsNullOrWhiteSpace($cleanName)) {
$ProfileList += $cleanName
}
}
}
# Remove duplicates and sort
# WRAPPER: @(...) ensures this remains an array even if 1 result exists
$ProfileList = @($ProfileList | Select-Object -Unique | Sort-Object)
if ($ProfileList.Count -eq 0) {
Write-Warning "No Wi-Fi profiles found on this system."
return
}
# Display Menu
Write-Host "`nSelect a profile to analyze:" -ForegroundColor Yellow
$i = 1
foreach ($P in $ProfileList) {
Write-Host " [$i] $P"
$i++
}
# Get User Input
$Selection = Read-Host "`nEnter number (1-$($ProfileList.Count))"
# Validate and Run
if ($Selection -match "^\d+$" -and $Selection -ge 1 -and $Selection -le $ProfileList.Count) {
$SelectedProfile = $ProfileList[$Selection - 1]
Write-Host "`nAnalyzing '$SelectedProfile'..." -ForegroundColor Cyan
Process-SystemProfile -Name $SelectedProfile
} else {
Write-Error "Invalid selection."
}
} else {
# MODE D: Show Help (Default)
Write-Host "==================================================" -ForegroundColor Cyan
Write-Host " WI-FI PROFILE ANALYZER HELP" -ForegroundColor Cyan
Write-Host "==================================================" -ForegroundColor Cyan
Write-Host "`nThis tool analyzes Wi-Fi profiles to show Security and Certificate Trust details."
Write-Host "`n[OPTION 1] Interactive Menu (Recommended)" -ForegroundColor Yellow
Write-Host " Usage: .\Get-Wifi-Profile-Analyzer.ps1 -Interactive"
Write-Host "`n[OPTION 2] Analyze by Name" -ForegroundColor Yellow
Write-Host " Usage: .\Get-Wifi-Profile-Analyzer.ps1 -ProfileName `"ContosoWLAN`""
Write-Host "`n[OPTION 3] Analyze Exported File" -ForegroundColor Yellow
Write-Host " Usage: .\Get-Wifi-Profile-Analyzer.ps1 -Path `"C:\Temp\Profile.xml`""
Write-Host "`n--------------------------------------------------" -ForegroundColor DarkGray
Write-Host "HANDY MANUAL COMMANDS (NETSH)" -ForegroundColor DarkGray
Write-Host "--------------------------------------------------" -ForegroundColor DarkGray
Write-Host " > To list all profiles on your PC:"
Write-Host " netsh wlan show profiles" -ForegroundColor White
Write-Host "`n > To manually export a profile to XML:"
Write-Host " netsh wlan export profile name=`"ContosoWLAN`" folder=`".`"" -ForegroundColor White
Write-Host "`n==================================================" -ForegroundColor Cyan
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment