<# .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 "" -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 }