WifiConnectionAPI.psm1
|
<#
.Synopsis Wifi .Description Manage Wifi connections .Parameter Get-RadioState .Parameter Set-RadioState .Parameter Get-WifiDeviceInformation .Parameter Get-WiFiAvailableAdapter .Parameter Get-WifiConnectionProfile .Parameter Remove-WifiConnectionProfile .Parameter Get-WifiCurrentConection .Parameter Get-WifiAvailableNetworks .Parameter Disconnect-WifiNetwork .Parameter Connect-WiFiNetwork #> ImportSystemModules Add-Type -AssemblyName System.Runtime.WindowsRuntime $asTaskGeneric=([System.WindowsRuntimeSystemExtensions].GetMethods()|Where-Object{$_.Name -eq 'AsTask' -and $_.GetParameters().Count -eq 1 -and $_.GetParameters()[0].ParameterType.Name -eq 'IAsyncOperation`1'})[0] Function Await($WinRtTask, $ResultType){ $asTask=$asTaskGeneric.MakeGenericMethod($ResultType) $netTask=$asTask.Invoke($null, @($WinRtTask)) $netTask.Wait(-1)|Out-Null return $netTask.Result } [Windows.Devices.Radios.Radio,Windows.System.Devices,ContentType=WindowsRuntime] | Out-Null [Windows.Devices.Radios.RadioState,Windows.System.Devices,ContentType=WindowsRuntime] | Out-Null [Windows.Devices.Radios.RadioAccessStatus,Windows.System.Devices,ContentType=WindowsRuntime] | Out-Null Function Get-RadioState { <# .SYNOPSIS Haalt alle beschikbare radio-adapters op (WiFi, Bluetooth, Mobiel) en toont hun huidige status. .DESCRIPTION Deze functie gebruikt de Windows Runtime (WinRT) API om directe toegang te krijgen tot de radio-hardware van het systeem. Het resultaat is een lijst van Radio-objecten die direct gepiped kunnen worden naar Set-RadioState. .EXAMPLE Get-RadioState Toont alle radio's en of ze 'On' of 'Off' zijn. .EXAMPLE Get-RadioState | Where-Object Kind -eq 'WiFi' | Set-RadioState -SetState Off Zoekt specifiek de WiFi-radio en schakelt deze uit. .OUTPUTS Windows.Devices.Radios.Radio #> [outputType([Windows.Devices.Radios.Radio])] param() $accessStatus = Await ([Windows.Devices.Radios.Radio]::RequestAccessAsync()) ([Windows.Devices.Radios.RadioAccessStatus]) if($accessStatus -eq "Allowed"){ Await ([Windows.Devices.Radios.Radio]::GetRadiosAsync()) ([System.Collections.Generic.IReadOnlyList[Windows.Devices.Radios.Radio]]) } else { Write-Warning "Geen toegang tot de radio-hardware. Status: $accessStatus" } } Function Set-RadioState{ <# .SYNOPSIS Schakelt een specifieke radio aan of uit. .DESCRIPTION Ontvangt Radio-objecten (meestal via de pipeline van Get-RadioState) en probeert de fysieke status te wijzigen naar 'On' of 'Off'. .PARAMETER SetState De gewenste doelstatus. Gebruik 'On' of 'Off'. (Heeft autocomplete support). .PARAMETER Radios Het Radio-object dat moet worden aangepast. Accepteert input via de pipeline. .EXAMPLE Get-RadioState | Set-RadioState -SetState Off Get-Radiostate | where-object Name -eq 'Wi-Fi'| Set-RadioSTate -SetState On Probeert alle radio's op het systeem uit te schakelen. .NOTES Sommige adapters (zoals Mobile Broadband) kunnen de statuswijziging weigeren als deze door het systeem elders beheerd worden. De functie zal in dat geval een waarschuwing geven in plaats van te crashen. #> param( [Parameter(Mandatory=$true)][ArgumentCompleter({ param($commandName,$parameterName,$wordToComplete,$commandAst,$fakeBoundParameters) $possibleValues=@{Values=@([Windows.Devices.Radios.RadioState]::On,[Windows.Devices.Radios.RadioState]::Off)} if($fakeBoundParameters.ContainsKey('Type')){ $possibleValues[$fakeBoundParameters.Type]| Where-object {$_ -like "$wordToComplete*"} }else{ $possibleValues.Values|Foreach-Object{$_} } })]$SetState, [parameter(Mandatory=$true,ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)][Windows.Devices.Radios.Radio][alias("Radio")][array]$Radios ) begin { } process{ $Radios.Gettype() Await ($Radios.SetStateAsync($SetState)) ([Windows.Devices.Radios.RadioAccessStatus]) } end{} } [Windows.Devices.WiFi.WiFiAdapter,Windows.Devices.Wifi,ContentType=WindowsRunTime]|Out-Null [Windows.Devices.Enumeration.DeviceInformation,Windows.Devices.Enumeration,ContentType=WindowsRunTime]|Out-Null [Windows.Security.Credentials.PasswordCredential,Windows.Security.Credentials,ContentType=WindowsRunTime]|Out-Null [Windows.Networking.Connectivity.NetworkInformation,Windows.Networking.Connectivity,Contenttype=WindowsRuntime]| Out-Null Function Get-WifiDeviceInformation{ [OutputType([Windows.Devices.Enumeration.DeviceInformationCollection])] Param() Await([Windows.Devices.Enumeration.DeviceInformation]::FindAllAsync([Windows.Devices.WiFi.WiFiAdapter]::GetDeviceSelector()))([Windows.Devices.Enumeration.DeviceInformationCollection]) } Function Get-WiFiAvailableAdapter{ #[outputtype([Windows.Devices.WiFi.WiFiAdapter],ParameterSetName="WiFiAvailableAdapter")] [outputtype([Windows.Devices.WiFi.WiFiAdapter])] param() Await([Windows.Devices.WiFi.WiFiAdapter]::FindAllAdaptersAsync())([System.Collections.Generic.IReadOnlyList[Windows.Devices.WiFi.WiFiAdapter]]) } Function Get-WifiConnectionProfile{ [outputType([Windows.Networking.Connectivity.NetworkInformation])] param() [Windows.Networking.Connectivity.NetworkInformation]::GetConnectionProfiles()|Where-Object{$_.IsWlanConnectionProfile} } Function Remove-WifiConnectionProfile{ param( [parameter(Mandatory=$true,ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)][Windows.Networking.Connectivity.ConnectionProfile] [alias("Profile")] [array]$Profiles ) begin {} process{ if($Profiles.CanDelete){ Write-host ("Delete Profile {0}" -f $Profiles.ProfileName) $Profiles.TryDeleteAsync() | Out-Null }else{ Write-host ("Can't Delete Profile {0}" -f $Profiles.ProfileName) } } end{} } Function Get-WifiCurrentConection{ [outputtype([Windows.Networking.Connectivity.ConnectionProfile])] param() await((Get-WiFiAvailableAdapter).NetworkAdapter.GetConnectedProfileAsync()) ([Windows.Networking.Connectivity.ConnectionProfile]) } Function Disconnect-WifiNetwork { param( [Parameter(Mandatory=$false)] [int[]]$Index # Veranderd naar array voor meerdere indexen (bijv. 0, 2) ) $Adapters = Get-WiFiAvailableAdapter if ($null -eq $Adapters -or $Adapters.Count -eq 0) { Write-Warning "Geen WiFi-adapters gevonden om te verbreken." return } if ($PSBoundParameters.ContainsKey('Index')) { # Loop door elke opgegeven index heen foreach ($i in $Index) { if ($i -ge 0 -and $i -lt $Adapters.Count) { $adapterName = (Get-NetAdapter | Where-Object DeviceID -match $Adapters[$i].NetworkAdapter.NetworkAdapterId).InterfaceDescription Write-Host "Verbinding verbreken op adapter index: $i : $adapterName" -ForegroundColor Cyan $Adapters[$i].Disconnect() } else { Write-Warning "Index $i overgeslagen: bestaat niet (beschikbaar: 0 t/m $($Adapters.Count - 1))." } } } else { # DEFAULT: Alles platgoooien Write-Host "Verbinding verbreken op ALLE ($($Adapters.Count)) adapters..." -ForegroundColor Yellow $Adapters.Disconnect() } } Register-ArgumentCompleter -CommandName 'Disconnect-WifiNetwork' -ParameterName 'Index' -ScriptBlock { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) $adapters = Get-WiFiAvailableAdapter for ($i = 0; $i -lt $adapters.Count; $i++) { $id = $adapters[$i].NetworkAdapter.NetworkAdapterId $name = (Get-NetAdapter | Where-Object DeviceID -match $id).InterfaceDescription [System.Management.Automation.CompletionResult]::new($i, $i, 'ParameterValue', "Adapter $i : $name") } } Function Get-WifiAvailableNetworks{ (Get-WiFiAvailableAdapter).NetworkReport.AvailableNetworks } Function Connect-WiFiNetwork { <# .SYNOPSIS Verbindt één, meerdere of alle WiFi-adapters met een specifiek netwerk (SSID). .DESCRIPTION Deze functie gebruikt de WinRT API om verbinding te maken. Het ondersteunt het gelijktijdig aansturen van specifieke adapters via hun index. Indien een netwerk al bekend is bij Windows (profiel aanwezig), is het wachtwoord niet verplicht. .PARAMETER Ssid De naam van het WiFi-netwerk. Gebruik de TAB-toets voor suggesties van beschikbare netwerken in de buurt. .PARAMETER Password Het wachtwoord voor het netwerk. Dit is een dynamische parameter die SecureString gebruikt (tenzij -AsPlainText is opgegeven). Niet verplicht als er al een opgeslagen profiel bestaat. .PARAMETER Index De index van de adapter(s) (bijv. 0, 1). Laat dit leeg om de verbinding op ALLE beschikbare WiFi-adapters tegelijk te proberen. .PARAMETER User Optionele gebruikersnaam voor enterprise-netwerken (802.1X). .PARAMETER Bssid Forceer verbinding met een specifiek Access Point op basis van het MAC-adres. .EXAMPLE Connect-WiFiNetwork -Ssid "MijnThuisNetwerk" -Index 0 Verbindt de eerste adapter met het opgegeven netwerk. .EXAMPLE Connect-WiFiNetwork -Ssid "Open_WiFi" Probeert alle WiFi-adapters op het systeem te verbinden met een open netwerk. .EXAMPLE Connect-WiFiNetwork -Ssid "Bedrijf_WiFi" -Password (Read-Host -AsSecureString) -Index 0, 2 Verbindt adapter 0 en 2 met een beveiligd netwerk met handmatige wachtwoordinvoer. .NOTES Versie: 2.0.0.0 De functie controleert per adapter of de SSID zichtbaar is voordat de verbinding wordt gestart. #> [CmdletBinding()] param( [string]$User, [string]$Bssid, [Switch]$AsPlainText, [Parameter(Mandatory=$true)]$Ssid, [int[]]$Index ) DynamicParam { # Kies het type op basis van de switch $parameterType = if ($AsPlainText) { [string] } else { [securestring] } # Maak de collectie voor attributen (zoals Mandatory) $attributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute] $attribute = New-Object System.Management.Automation.ParameterAttribute $attribute.Mandatory = $false $attributeCollection.Add($attribute) # Definieer de parameter 'Password' runtime $dynParam = New-Object System.Management.Automation.RuntimeDefinedParameter('Password', $parameterType, $attributeCollection) # Voeg toe aan de dictionary die PowerShell terug verwacht $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $paramDictionary.Add('Password', $dynParam) return $paramDictionary } Process{ $PasswordValue = $PSBoundParameters['Password'] $SsidValue = $PSBoundParameters['Ssid'] # 1. Haal de adapters op $AllAdapters = Get-WiFiAvailableAdapter # 2. Bepaal op welke adapters we actie ondernemen $TargetAdapters = if ($PSBoundParameters.ContainsKey('Index')) { foreach($i in $Index) { $AllAdapters[$i] } } else { $AllAdapters # Standaard: Probeer op ALLE adapters te verbinden } $Credentials=[Windows.Security.Credentials.PasswordCredential]::new() if($null -ne $passwordValue){ if($AsPlainText){ $Credentials.Password=$passwordValue }else{ $Credentials.Password=([System.Net.NetworkCredential]::new([string]::empty,$passwordValue)).Password } } if([bool]$User){ $Credentials.UserName=$User } $TargetAdapters | Foreach-Object { # Haal de menselijke naam op voor de huidige adapter in de loop $currentId = $_.NetworkAdapter.NetworkAdapterId $adapterName = (Get-NetAdapter | Where-Object DeviceID -match $currentId).InterfaceDescription Write-Host "Verbinden via adapter: $adapterName" -ForegroundColor Cyan if(-not $Bssid){ $Network=$_.NetworkReport.AvailableNetworks|Where-Object{$_.Ssid -match $SsidValue}| Sort-Object NetworkRssiInDecibelMilliwatts -Descending | Select-Object -First 1 }else{ $Network=$_.NetworkReport.AvailableNetworks|Where-Object{$_.BSsid -match $BSsid} } $_.Disconnect() $Result = Await($_.ConnectAsync($Network,[Windows.Devices.WiFi.WiFiReconnectionKind]::Automatic,$Credentials,$null))([Windows.Devices.WiFi.WiFiConnectionResult]) # Optioneel: Laat direct weten of het gelukt is voor deze specifieke kaart $statusColor = "Yellow" if ($Result.ConnectionStatus -eq "Success") { $statusColor = "Green" } Write-Host "Status voor $adapterName : $($Result.ConnectionStatus)" -ForegroundColor $statusColor [PSCustomObject]@{ ConnectionStatus = $Result.ConnectionStatus # NIET hernoemen! AdapterName = $adapterName Ssid = $SsidValue Index = [array]::IndexOf($AllAdapters, $_) Bssid = $Network.Bssid } } } } Register-ArgumentCompleter -CommandName 'Connect-WiFiNetwork' -ParameterName 'Ssid' -ScriptBlock { param ($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) # 1. Haal de adapters op die de gebruiker heeft opgegeven (of allemaal) $allAdapters = Get-WiFiAvailableAdapter $targetIndices = if ($fakeBoundParameters.ContainsKey('Index')) { $fakeBoundParameters.Index } else { 0..($allAdapters.Count - 1) } # 2. Haal de netwerken op SPECIFIEK voor deze adapters $networks = foreach ($i in $targetIndices) { $allAdapters[$i].NetworkReport.AvailableNetworks | Where-Object { -not [string]::IsNullOrEmpty($_.Ssid) } } # 3. Maak de unieke lijst van SSIDs $possibleValues = $networks | Select-Object -ExpandProperty Ssid -Unique | ForEach-Object { $formattedSsid = if ($_ -match ' ') { "`"$_`"" } else { $_ } [PscustomObject]@{ Ssid = $formattedSsid } } # 4. Filter op wat de gebruiker typt if ([string]::IsNullOrEmpty($wordToComplete)) { $possibleValues | Select-Object -ExpandProperty Ssid } else { # Fix: Zorg dat we op de juiste property filteren $possibleValues | Where-Object { $_.Ssid -like "$wordToComplete*" } | Select-Object -ExpandProperty Ssid } } Register-ArgumentCompleter -CommandName 'Connect-WiFiNetwork' -ParameterName 'Index' -ScriptBlock { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) $adapters = Get-WiFiAvailableAdapter for ($i = 0; $i -lt $adapters.Count; $i++) { $name = $adapters[$i].NetworkAdapter.NetworkItem.NetworkId # Of gebruik Get-NetAdapter voor de 'echte' naam [System.Management.Automation.CompletionResult]::new($i, $i, 'ParameterValue', "Adapter $i : $name") } } Export-ModuleMember Get-RadioState Export-ModuleMember Set-RadioState Export-ModuleMember Get-WifiDeviceInformation Export-Modulemember Get-WiFiAvailableAdapter Export-ModuleMember Get-WifiAvailableNetworks Export-ModuleMember Get-WifiConnectionProfile Export-Modulemember Remove-WifiConnectionProfile Export-ModuleMember Get-WifiCurrentConection Export-ModuleMember Disconnect-WifiNetwork Export-ModuleMember Connect-WiFiNetwork |