Core/Public/Wifi/Connect-WifiNetwork.ps1
|
Function Connect-WifiNetwork { [CmdletBinding()] param( [Parameter(Mandatory = $true)]$Ssid, [string]$Bssid, [string]$User, [Switch]$AsPlainText, [Switch]$Hidden, [int[]]$Index, [Windows.Devices.WiFi.WiFiReconnectionKind]$WifiReconnectionKind = [Windows.Devices.WiFi.WiFiReconnectionKind]::Automatic ) DynamicParam { # Choice type depending on Switch $parameterType = if ($AsPlainText) { [string] } else { [securestring] } # Create the attributeCollection for all attributes like Mandatory $attributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute] $attribute = New-Object System.Management.Automation.ParameterAttribute $attribute.Mandatory = $false $attributeCollection.Add($attribute) # Define the 'Password' paramter at runtime $dynParam = New-Object System.Management.Automation.RuntimeDefinedParameter('Password', $parameterType, $attributeCollection) # Add to the Dictionary wich powreshell expects to receive $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('Password', $dynParam) return $paramDictionary } Process { $Adapters = Get-WiFiAvailableAdapters if (-not $Adapters) { throw "No active WiFi-adapter found." } $Radios = Get-RadioState | Where-Object Kind -eq 'WiFi' if ($Radios.Count -gt 0 -and -not ($Radios | Where-Object State -eq 'On')) { throw "Error: All WiFi radios are OFF. Turn them on first." } # --- 2. Prepair Credentials --- $Pass = $PSBoundParameters['Password'] $Creds = [Windows.Security.Credentials.PasswordCredential]::new() if ($null -ne $Pass) { if ($AsPlainText) { $Creds.Password = $Pass } else { $Creds.Password = ([System.Net.NetworkCredential]::new("", $Pass)).Password } } if ($User) { $Creds.UserName = $User } # --- 3. Getting the adapters you want to control --- $Targets = if ($PSBoundParameters.ContainsKey('Index')) { $Index | ForEach-Object { $Adapters[$_] } } else { $Adapters } # --- 4. Connection Loop --- $Targets | ForEach-Object { $currentId = $_.NetworkAdapter.NetworkAdapterId $name = (Get-NetAdapter | Where-Object DeviceID -match $currentId).InterfaceDescription # Search the network specifick for this $Net = $_.NetworkReport.AvailableNetworks | Where-Object { if ($Bssid) { $_.Bssid -eq $Bssid } else { $_.Ssid -eq $Ssid } } | Sort-Object NetworkRssiInDecibelMilliwatts -Descending | Select-Object -First 1 if (-not $Net -and -not $Hidden) { # Force Scan if not found $null = Get-wifiAvailableNetworks $Net = $_.NetworkReport.AvailableNetworks | Where-Object { if ($Bssid) { $_.Bssid -eq $Bssid } else { $_.Ssid -eq $Ssid } } | Select-Object -First 1 } if (-not $Net) { Write-Warning "Adapter $($name): SSID '$($Ssid)' not found."; return } Write-Host "Connecting $name to $Ssid..." -ForegroundColor Cyan $_.Disconnect() $_Ssid = $null if ($Hidden) { $_Ssid = $Ssid # Pass the SSID if it's a hidden network } $ConnectAsync = $_.ConnectAsync($Net, $wifiReconnectionKind, $creds, $_Ssid) start-sleep -Milliseconds 50 while ($ConnectAsync.Status -eq [Windows.Foundation.AsyncStatus]::Started) { start-sleep -Milliseconds 100 } $Results = $ConnectAsync.GetResults() [PSCustomObject]@{ ConnectionStatus = $Results.ConnectionStatus AdapterName = $name Ssid = $Ssid Bssid = $Net.Bssid } } } } <#$SsidCompleter = { param($CommandName, $ParameterName, $WordToComplete, $CommandAst, $FakeBoundParameters) try { $LocationAccess = &$ScriptBlockCheckLocationAccess if ($LocationAccess) { return $LocationAccess } $radioStatus = &$ScriptBlockCheckRadioOff if ($radioStatus) { return $radioStatus } # Haal de netwerken op $Networks = @(Get-WiFiAvailableNetworks) # Filter: Alleen SSIDs die NIET leeg/null zijn en overeenkomen met wat getypt is $Networks | Sort-Object NetworkRssiInDecibelMilliwatts -Descending | Where-Object { -not [string]::IsNullOrWhiteSpace($_.Ssid) -and $_.Ssid -like "$WordToComplete*" } | Select-Object -ExpandProperty Ssid -Unique | ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) } } catch {} }#> $SsidCompleter = { param($CommandName, $ParameterName, $WordToComplete, $CommandAst, $FakeBoundParameters) try { $LocationAccess = &$ScriptBlockCheckLocationAccess if ($LocationAccess) { return $LocationAccess } $radioStatus = &$ScriptBlockCheckRadioOff if ($radioStatus) { return $radioStatus } # 1. GEt all networks and filter on input $Networks = @(Get-WiFiAvailableNetworks) | Where-Object { -not [string]::IsNullOrWhiteSpace($_.Ssid) -and $_.Ssid -like "$WordToComplete*" } # 2. Group per SSID $Groups = $Networks | Group-Object Ssid | ForEach-Object { [PSCustomObject]@{ Ssid = $_.Name Count = $_.Count MaxRssi = ($_.Group | Measure-Object NetworkRssiInDecibelMilliwatts -Maximum).Maximum } } # 3. Sort groups on signal strenght $Groups | Sort-Object MaxRssi -Descending | ForEach-Object { [System.Management.Automation.CompletionResult]::new( $_.Ssid, # the value $_.Ssid, # Text in list 'ParameterValue', # Type "Zichtbare netwerken: $($_.Count)" # Tooltip with the number of networks nearby ) } } catch {} } Register-ArgumentCompleter -CommandName 'Connect-WifiNetwork' -ParameterName 'Ssid' -ScriptBlock $SsidCompleter $BssidCompleter = { param($CommandName, $ParameterName, $WordToComplete, $CommandAst, $FakeBoundParameters) try { $LocationAccess = &$ScriptBlockCheckLocationAccess if ($LocationAccess) { return $LocationAccess } $radioStatus = &$ScriptBlockCheckRadioOff if ($radioStatus) { return $radioStatus } # 1. Get A list of networks sort by signal strength strongest on top $Networks = @(Get-WiFiAvailableNetworks) | Sort-Object NetworkRssiInDecibelMilliwatts -Descending $IsHiddenRequested = $FakeBoundParameters.ContainsKey('Hidden') $SelectedSsid = $FakeBoundParameters['Ssid'] $Networks | Where-Object { $HasNoSsid = [string]::IsNullOrWhiteSpace($_.Ssid) $MatchBssid = $_.Bssid -like "$WordToComplete*" if ($IsHiddenRequested) { # show hidden networks (BSSIDS without name ) $HasNoSsid -and $MatchBssid } else { # Show SSid only if have value $Condition = -not $HasNoSsid -and $MatchBssid # Filter extra on SSID if filled if ($SelectedSsid) { $Condition = $Condition -and ($_.Ssid -eq $SelectedSsid) } $Condition } } | ForEach-Object { $Signal = "$($_.NetworkRssiInDecibelMilliwatts) dBm" $ToolTip = if ($IsHiddenRequested) { "Sterkte: $Signal [HIDDEN]" } else { "SSID: $($_.Ssid) | Sterkte: $Signal | Band $(Get-WifiBandName $_.ChannelCenterFrequencyInKilohertz)" } # CompletionResult: Value, Visual, type, tooltip [System.Management.Automation.CompletionResult]::new($_.Bssid, $_.Bssid, 'ParameterValue', $ToolTip) } } catch {} } Register-ArgumentCompleter -CommandName 'Connect-WifiNetwork' -ParameterName 'Bssid' -ScriptBlock $BssidCompleter $ConnectIndexCompleter = { param($CommandName, $ParameterName, $WordToComplete, $CommandAst, $FakeBoundParameters) try { $AsyncOp = [Windows.Devices.WiFi.WiFiAdapter]::FindAllAdaptersAsync() while ($AsyncOp.Status -eq [Windows.Foundation.AsyncStatus]::Started) { Start-Sleep -Milliseconds 10 } $Adapters = @($AsyncOp.GetResults()) $AlreadySelected = @() if ($FakeBoundParameters.ContainsKey('Index')) { $AlreadySelected = @($FakeBoundParameters['Index']) } for ($i = 0; $i -lt $Adapters.Count; $i++) { if ($i -in $AlreadySelected) { continue } $Name = $Adapters[$i].NetworkAdapter.NetworkAdapterId $CompletionText = $i.ToString() $ListItemText = "$i ($Name)" $ToolTip = "Verbind via adapter $($i): $Name" [System.Management.Automation.CompletionResult]::new($CompletionText, $ListItemText, 'ParameterValue', $ToolTip) } } catch {} } Register-ArgumentCompleter -CommandName 'Connect-WifiNetwork' -ParameterName 'Index' -ScriptBlock $ConnectIndexCompleter |