Created
August 19, 2025 22:38
-
-
Save Freundschaft/7667acd31aa834705cd24b49a8079526 to your computer and use it in GitHub Desktop.
wifi-pcie-control.ps1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Simple WiFi/PCIe Root Port Controller | |
# Run as Administrator | |
param( | |
[switch]$DisableWiFi, | |
[switch]$EnableWiFi, | |
[switch]$DisableRootPort, | |
[switch]$EnableRootPort, | |
[int]$RootPortIndex = -1, | |
[switch]$ShowOnly | |
) | |
# Check if running as administrator | |
if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { | |
Write-Error "This script must be run as Administrator!" | |
exit 1 | |
} | |
function Get-WiFiDevice { | |
Write-Host "Searching for WiFi device (including hidden devices)..." -ForegroundColor Gray | |
# Method 1: Look for active WiFi device | |
$activeWifi = Get-WmiObject -Class Win32_PnPEntity | Where-Object { | |
$_.DeviceID -eq "PCI\VEN_17CB&DEV_1107&SUBSYS_E0E617AA&REV_01\4&A3048F2&1&0012" -and | |
$_.ConfigManagerErrorCode -eq 0 | |
} | |
if ($activeWifi) { | |
Write-Host "Found active WiFi device: $($activeWifi.Name)" -ForegroundColor Green | |
return $activeWifi | |
} | |
# Method 2: Look for ALL PnP entities including hidden ones | |
Write-Host "Searching all PnP entities (including hidden)..." -ForegroundColor Yellow | |
# Use CIM instead of WMI for better hidden device detection | |
try { | |
$allDevices = Get-CimInstance -ClassName Win32_PnPEntity | |
# Look for our specific WiFi device | |
$wifiDevice = $allDevices | Where-Object { | |
$_.DeviceID -eq "PCI\VEN_17CB&DEV_1107&SUBSYS_E0E617AA&REV_01\4&A3048F2&1&0012" | |
} | |
if ($wifiDevice) { | |
$status = switch ($wifiDevice.ConfigManagerErrorCode) { | |
0 { "active" } | |
22 { "disabled" } | |
24 { "not present/phantom" } | |
28 { "no drivers" } | |
45 { "hardware disabled" } | |
default { "error code $($wifiDevice.ConfigManagerErrorCode)" } | |
} | |
Write-Host "Found WiFi device via CIM (state: $status): $($wifiDevice.Name)" -ForegroundColor Green | |
return $wifiDevice | |
} | |
# Look for any Qualcomm devices | |
$qualcommDevices = $allDevices | Where-Object { | |
$_.DeviceID -like "PCI\VEN_17CB*" | |
} | |
if ($qualcommDevices.Count -gt 0) { | |
Write-Host "Found Qualcomm devices via CIM:" -ForegroundColor Cyan | |
$qualcommDevices | ForEach-Object { | |
$status = switch ($_.ConfigManagerErrorCode) { | |
0 { "Active" } | |
22 { "Disabled" } | |
24 { "Not present/Phantom" } | |
28 { "No drivers" } | |
45 { "Hardware disabled" } | |
default { "Error $($_.ConfigManagerErrorCode)" } | |
} | |
Write-Host " $($_.Name) - $status" -ForegroundColor Cyan | |
Write-Host " ID: $($_.DeviceID)" -ForegroundColor DarkGray | |
} | |
# Return the first one that matches our WiFi pattern | |
$wifiMatch = $qualcommDevices | Where-Object { | |
$_.Name -like "*FastConnect*" -or $_.Name -like "*Wi-Fi*" | |
} | Select-Object -First 1 | |
if ($wifiMatch) { | |
return $wifiMatch | |
} | |
return $qualcommDevices[0] | |
} | |
} catch { | |
Write-Host "CIM query failed, falling back to WMI..." -ForegroundColor Yellow | |
} | |
# Method 3: Try registry-based approach for phantom devices | |
Write-Host "Checking registry for phantom devices..." -ForegroundColor Yellow | |
try { | |
$enumKey = "HKLM:\SYSTEM\CurrentControlSet\Enum\PCI" | |
if (Test-Path $enumKey) { | |
$pciDevices = Get-ChildItem $enumKey | |
foreach ($device in $pciDevices) { | |
if ($device.Name -like "*VEN_17CB*") { | |
$deviceInstances = Get-ChildItem $device.PSPath | |
foreach ($instance in $deviceInstances) { | |
$deviceProps = Get-ItemProperty $instance.PSPath -ErrorAction SilentlyContinue | |
if ($deviceProps.DeviceDesc -like "*Qualcomm*" -and $deviceProps.DeviceDesc -like "*Wi-Fi*") { | |
Write-Host "Found WiFi in registry: $($deviceProps.DeviceDesc)" -ForegroundColor Green | |
# Extract the device ID from the registry path | |
$registryPath = $instance.Name | |
$deviceID = $registryPath -replace "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Enum\\", "" | |
$deviceID = $deviceID -replace "\\", "\" | |
Write-Host " Device ID from registry: $deviceID" -ForegroundColor Gray | |
# Create a synthetic device object with the essential properties | |
$syntheticDevice = New-Object PSObject -Property @{ | |
DeviceID = $deviceID | |
Name = $deviceProps.DeviceDesc -replace "@.*?%;", "" # Clean up the description | |
ConfigManagerErrorCode = 24 # Phantom device | |
Status = "Unknown" | |
} | |
Write-Host "Created synthetic device object for phantom WiFi" -ForegroundColor Green | |
return $syntheticDevice | |
} | |
} | |
} | |
} | |
} | |
} catch { | |
Write-Host "Registry check failed: $($_.Exception.Message)" -ForegroundColor Red | |
} | |
# Method 4: Fallback to original WMI approach | |
Write-Host "Fallback: Checking visible devices only..." -ForegroundColor Yellow | |
$allWifiDevices = Get-WmiObject -Class Win32_PnPEntity | Where-Object { | |
$_.Name -like "*Qualcomm FastConnect*" -and $_.DeviceID -like "PCI\*" | |
} | |
if ($allWifiDevices.Count -gt 0) { | |
return $allWifiDevices[0] | |
} | |
Write-Host "No WiFi device found in any location" -ForegroundColor Red | |
return $null | |
} | |
function Find-WiFiRootPort { | |
param($WiFiDevice) | |
if (-not $WiFiDevice) { | |
return $null | |
} | |
Write-Host "Finding root port for WiFi device..." -ForegroundColor Cyan | |
# Extract location info from WiFi device | |
# WiFi: PCI\VEN_17CB&DEV_1107&SUBSYS_E0E617AA&REV_01\4&A3048F2&1&0012 | |
# Location pattern: 4&A3048F2&1&0012 | |
$wifiLocation = ($WiFiDevice.DeviceID -split '\\')[-1] | |
Write-Host "WiFi Location: $wifiLocation" -ForegroundColor Gray | |
# Extract the bus/device info - typically the last part after & | |
$wifiLocationParts = $wifiLocation -split '&' | |
$wifiBusInfo = $wifiLocationParts[-1] # Should be "0012" | |
Write-Host "WiFi Bus Info: $wifiBusInfo" -ForegroundColor Gray | |
# Get all root ports | |
$allRootPorts = Get-RootPorts | |
Write-Host "Checking $($allRootPorts.Count) root ports..." -ForegroundColor Gray | |
# Method 1: Try to find parent-child relationship | |
Write-Host "Method 1: Checking parent-child relationships..." -ForegroundColor Gray | |
try { | |
$wifiDeviceID = $WiFiDevice.DeviceID.Replace('\', '\\') | |
$parentRelations = Get-WmiObject -Class Win32_SystemDevices | Where-Object { | |
$_.PartComponent -like "*$wifiDeviceID*" | |
} | |
foreach ($relation in $parentRelations) { | |
$parentDeviceID = ($relation.GroupComponent -split '"')[1] | |
$parentDevice = $allRootPorts | Where-Object { $_.DeviceID -eq $parentDeviceID } | |
if ($parentDevice) { | |
Write-Host "✓ Found via parent relationship: $($parentDevice.Name)" -ForegroundColor Green | |
return $parentDevice | |
} | |
} | |
} catch { | |
Write-Host "Parent relationship check failed, trying location matching..." -ForegroundColor Yellow | |
} | |
# Method 2: Location-based matching | |
Write-Host "Method 2: Checking location patterns..." -ForegroundColor Gray | |
foreach ($rootPort in $allRootPorts) { | |
$rootLocation = ($rootPort.DeviceID -split '\\')[-1] | |
$rootLocationParts = $rootLocation -split '&' | |
Write-Host " Checking root port: $($rootPort.Name)" -ForegroundColor Gray | |
Write-Host " Root location: $rootLocation" -ForegroundColor DarkGray | |
# Check if any part of the location matches | |
foreach ($wifiPart in $wifiLocationParts) { | |
foreach ($rootPart in $rootLocationParts) { | |
if ($wifiPart -eq $rootPart -and $wifiPart -ne "4" -and $wifiPart.Length -gt 1) { | |
Write-Host " ✓ Location match found: $wifiPart" -ForegroundColor Green | |
return $rootPort | |
} | |
} | |
} | |
} | |
# Method 3: Try to find root port with similar bus topology | |
Write-Host "Method 3: Checking bus topology..." -ForegroundColor Gray | |
# Look for root ports that might be on the same bus controller | |
# WiFi is on 4&A3048F2&1&0012, so look for root ports with A3048F2 | |
$busController = $wifiLocationParts[1] # "A3048F2" | |
foreach ($rootPort in $allRootPorts) { | |
if ($rootPort.DeviceID -like "*$busController*") { | |
Write-Host "✓ Found via bus controller match: $($rootPort.Name)" -ForegroundColor Green | |
Write-Host " Bus controller: $busController" -ForegroundColor Gray | |
return $rootPort | |
} | |
} | |
# Method 4: Check if the WiFi's last location digits match root port location | |
Write-Host "Method 4: Checking location digit patterns..." -ForegroundColor Gray | |
# WiFi ends with 0012, so check for root ports ending with 12 | |
foreach ($rootPort in $allRootPorts) { | |
$rootLocation = ($rootPort.DeviceID -split '\\')[-1] | |
if ($rootLocation -like "*&12" -or $rootLocation -like "*&0012") { | |
Write-Host "✓ Found via location digit match: $($rootPort.Name)" -ForegroundColor Green | |
Write-Host " Location match: $wifiBusInfo vs $rootLocation" -ForegroundColor Gray | |
return $rootPort | |
} | |
} | |
# Method 5: Smart guess based on T14 G5 architecture | |
Write-Host "Method 5: T14 G5 specific logic..." -ForegroundColor Gray | |
# On T14 G5, WiFi is often on one of the 14EE controllers (ports [3-5]) | |
$likelyPorts = $allRootPorts | Where-Object { $_.DeviceID -like "*DEV_14EE*" } | |
if ($likelyPorts.Count -gt 0) { | |
# Try the one ending in 12 first | |
$port12 = $likelyPorts | Where-Object { $_.DeviceID -like "*&12" } | |
if ($port12) { | |
Write-Host "✓ T14 G5 best guess (DEV_14EE + &12): $($port12.Name)" -ForegroundColor Green | |
return $port12 | |
} | |
# Otherwise return first 14EE port | |
Write-Host "✓ T14 G5 fallback guess (first DEV_14EE): $($likelyPorts[0].Name)" -ForegroundColor Yellow | |
return $likelyPorts[0] | |
} | |
Write-Warning "Could not automatically determine WiFi root port" | |
Write-Host "WiFi device location details:" -ForegroundColor Yellow | |
Write-Host " Full location: $wifiLocation" -ForegroundColor Gray | |
Write-Host " Bus controller: $busController" -ForegroundColor Gray | |
Write-Host " Bus info: $wifiBusInfo" -ForegroundColor Gray | |
return $null | |
} | |
function Get-RootPorts { | |
$rootPorts = Get-WmiObject -Class Win32_PnPEntity | Where-Object { | |
$_.Name -like "*PCI Express-Stammport*" -or $_.Name -like "*PCIe Root Port*" | |
} | Sort-Object DeviceID | |
return $rootPorts | |
} | |
function Toggle-Device { | |
param( | |
[Parameter(Mandatory=$true)] | |
$Device, | |
[Parameter(Mandatory=$true)] | |
[bool]$EnableDevice | |
) | |
$action = if ($EnableDevice) { "enable" } else { "disable" } | |
Write-Host "Attempting to $action $($Device.Name)" -ForegroundColor Cyan | |
if ($EnableDevice) { | |
$result = $Device.Enable() | |
} else { | |
$result = $Device.Disable() | |
} | |
switch ($result.ReturnValue) { | |
0 { Write-Host "✓ Successfully ${action}d!" -ForegroundColor Green; return $true } | |
1 { Write-Warning "✗ Not supported"; return $false } | |
2 { Write-Warning "✗ Access denied"; return $false } | |
22 { Write-Warning "✗ Device in use"; return $false } | |
default { Write-Warning "✗ Error: $($result.ReturnValue)"; return $false } | |
} | |
} | |
function Show-DeviceStatus { | |
param($Device, $Name) | |
if (-not $Device) { | |
Write-Host "$Name`: Not found" -ForegroundColor Red | |
return | |
} | |
$status = switch ($Device.ConfigManagerErrorCode) { | |
0 { "✓ Working properly" } | |
22 { "⚠ Disabled" } | |
28 { "✗ No drivers" } | |
default { "? Error code: $($Device.ConfigManagerErrorCode)" } | |
} | |
$color = switch ($Device.ConfigManagerErrorCode) { | |
0 { "Green" } | |
22 { "Yellow" } | |
default { "Red" } | |
} | |
Write-Host "$Name`: $status" -ForegroundColor $color | |
Write-Host " Device: $($Device.Name)" -ForegroundColor Gray | |
Write-Host " ID: $($Device.DeviceID)" -ForegroundColor Gray | |
} | |
# Main execution | |
Write-Host "Smart WiFi/PCIe Controller" -ForegroundColor Magenta | |
Write-Host "===========================" -ForegroundColor Magenta | |
# Get devices | |
$wifiDevice = Get-WiFiDevice | |
$wifiRootPort = Find-WiFiRootPort -WiFiDevice $wifiDevice | |
if ($ShowOnly) { | |
Write-Host "`nCurrent Status:" -ForegroundColor Cyan | |
if ($wifiDevice) { | |
Show-DeviceStatus -Device $wifiDevice -Name "WiFi Device" | |
if ($wifiRootPort) { | |
Write-Host "`nWiFi Root Port:" -ForegroundColor Cyan | |
Show-DeviceStatus -Device $wifiRootPort -Name "WiFi Root Port" | |
} else { | |
Write-Host "`nWiFi Root Port: Not found automatically" -ForegroundColor Red | |
} | |
} else { | |
Write-Host "WiFi Device: Not found" -ForegroundColor Red | |
Write-Host "Checking for disabled devices..." -ForegroundColor Yellow | |
# Show all Qualcomm devices regardless of state | |
$allQualcomm = Get-WmiObject -Class Win32_PnPEntity | Where-Object { | |
$_.DeviceID -like "PCI\VEN_17CB*" | |
} | |
if ($allQualcomm.Count -gt 0) { | |
Write-Host "Found Qualcomm devices:" -ForegroundColor Yellow | |
$allQualcomm | ForEach-Object { | |
$status = switch ($_.ConfigManagerErrorCode) { | |
0 { "✓ Working" } | |
22 { "⚠ Disabled" } | |
28 { "✗ No drivers" } | |
24 { "✗ Not present" } | |
default { "? Error $($_.ConfigManagerErrorCode)" } | |
} | |
Write-Host " $status - $($_.Name)" -ForegroundColor Gray | |
Write-Host " ID: $($_.DeviceID)" -ForegroundColor DarkGray | |
} | |
} | |
} | |
if (-not $wifiRootPort) { | |
Write-Host "`nAvailable Root Ports:" -ForegroundColor Yellow | |
$allRootPorts = Get-RootPorts | |
for ($i = 0; $i -lt $allRootPorts.Count; $i++) { | |
$status = switch ($allRootPorts[$i].ConfigManagerErrorCode) { | |
0 { "✓ Active" } | |
22 { "⚠ Disabled" } | |
default { "? Error" } | |
} | |
Write-Host "[$i] $($allRootPorts[$i].Name) - $status" -ForegroundColor White | |
Write-Host " ID: $($allRootPorts[$i].DeviceID)" -ForegroundColor Gray | |
} | |
Write-Host "`nYou can manually specify: -RootPortIndex X" -ForegroundColor Yellow | |
} | |
Write-Host "`nUsage Examples:" -ForegroundColor Yellow | |
Write-Host " .\script.ps1 -DisableWiFi # Disable WiFi adapter" -ForegroundColor Gray | |
Write-Host " .\script.ps1 -DisableRootPort # Disable WiFi's root port" -ForegroundColor Gray | |
Write-Host " .\script.ps1 -EnableWiFi # Re-enable WiFi" -ForegroundColor Gray | |
Write-Host " .\script.ps1 -EnableRootPort # Re-enable WiFi's root port" -ForegroundColor Gray | |
exit 0 | |
} | |
# WiFi operations | |
if ($DisableWiFi) { | |
if ($wifiDevice) { | |
Write-Host "`nDisabling WiFi adapter..." -ForegroundColor Red | |
$success = Toggle-Device -Device $wifiDevice -EnableDevice $false | |
if ($success) { | |
Write-Host "WiFi disabled. Check if other devices can now enter D3 state." -ForegroundColor Yellow | |
} | |
} else { | |
Write-Error "WiFi device not found!" | |
} | |
exit 0 | |
} | |
if ($EnableWiFi) { | |
if ($wifiDevice) { | |
Write-Host "`nEnabling WiFi adapter..." -ForegroundColor Green | |
Toggle-Device -Device $wifiDevice -EnableDevice $true | |
} else { | |
Write-Error "WiFi device not found!" | |
} | |
exit 0 | |
} | |
# Root port operations | |
if ($DisableRootPort) { | |
$targetPort = $null | |
if ($RootPortIndex -ge 0) { | |
# Manual selection | |
$allRootPorts = Get-RootPorts | |
if ($RootPortIndex -lt $allRootPorts.Count) { | |
$targetPort = $allRootPorts[$RootPortIndex] | |
Write-Host "Using manually selected root port [$RootPortIndex]" -ForegroundColor Yellow | |
} else { | |
Write-Error "Invalid root port index. Use -ShowOnly to see available ports." | |
exit 1 | |
} | |
} else { | |
# Auto-detected | |
$targetPort = $wifiRootPort | |
if (-not $targetPort) { | |
Write-Error "Could not auto-detect WiFi root port. Use -RootPortIndex X to specify manually." | |
exit 1 | |
} | |
Write-Host "Using auto-detected WiFi root port" -ForegroundColor Green | |
} | |
Write-Host "`nDisabling Root Port: $($targetPort.Name)" -ForegroundColor Red | |
$success = Toggle-Device -Device $targetPort -EnableDevice $false | |
if ($success) { | |
Write-Host "Root port disabled. WiFi will be completely unavailable." -ForegroundColor Yellow | |
Write-Host "Use -EnableRootPort to restore (no need to specify index)." -ForegroundColor Yellow | |
} | |
exit 0 | |
} | |
if ($EnableRootPort) { | |
$targetPort = $null | |
if ($RootPortIndex -ge 0) { | |
# Manual selection | |
$allRootPorts = Get-RootPorts | |
if ($RootPortIndex -lt $allRootPorts.Count) { | |
$targetPort = $allRootPorts[$RootPortIndex] | |
Write-Host "Using manually selected root port [$RootPortIndex]" -ForegroundColor Yellow | |
} else { | |
Write-Error "Invalid root port index." | |
exit 1 | |
} | |
} else { | |
# Auto-detection using disabled WiFi device | |
if ($wifiDevice) { | |
$targetPort = Find-WiFiRootPort -WiFiDevice $wifiDevice | |
if ($targetPort) { | |
Write-Host "Auto-detected root port via disabled WiFi device" -ForegroundColor Green | |
} | |
} | |
if (-not $targetPort) { | |
Write-Error "Could not determine which root port to enable. The WiFi device may be completely missing. Use -RootPortIndex X to specify manually, or check available ports with -ShowOnly." | |
exit 1 | |
} | |
} | |
Write-Host "`nEnabling Root Port: $($targetPort.Name)" -ForegroundColor Green | |
$success = Toggle-Device -Device $targetPort -EnableDevice $true | |
if ($success) { | |
Write-Host "Root port enabled. WiFi should be restored." -ForegroundColor Green | |
Write-Host "You may need to wait a moment for devices to re-initialize." -ForegroundColor Yellow | |
} | |
exit 0 | |
} | |
# No action specified | |
Write-Host "`nNo action specified. Use -ShowOnly to see available options." -ForegroundColor Yellow |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment