windowspowershellbluetoothwifi

PowerShell Script to Enable/Disable WiFi or Bluetooth Using WinRT APIs


I created a PowerShell script to programmatically enable or disable WiFi or Bluetooth radios on a Windows system using the Windows.Devices.Radios namespace and WinRT APIs. The script handles the asynchronous nature of WinRT APIs and works seamlessly to toggle the radio state.

Below is the implementation for enabling/disabling WiFi or Bluetooth radios.


Solution

  • This PowerShell script enables or disables WiFi or Bluetooth on Windows using the Windows.Devices.Radios namespace via WinRT APIs. Below is a detailed explanation of the script and how it works.

    # script to enable/disable WiFi or bluetooth in Windows
    # carsten.giese@googlemail.com
    
    cls
    Remove-Variable * -ea 0
    $ErrorActionPreference = 'stop'
    
    $newStatus = 'On' # On/Off
    
    Add-Type -AssemblyName System.Runtime.WindowsRuntime
    $methods = [System.WindowsRuntimeSystemExtensions].GetMethods()
    foreach($m in $methods) {
        if ($m.Name -ne 'AsTask') {continue}
        if ($m.GetParameters().Count -ne 1) {continue}
        if ($m.GetParameters()[0].ParameterType.Name -ne 'IAsyncOperation`1') {continue}
        $asTaskGeneric = $m
        break
    }
    
    function await($task, $type) {
        $asTask = $asTaskGeneric.MakeGenericMethod($type)
        $netTask = $asTask.Invoke($null, $task)
        $null = $netTask.Wait(-1)
        $netTask.Result
    }
    
    $radio  = [Windows.Devices.Radios.Radio]
    $rList  = [System.Collections.Generic.IReadOnlyList[Windows.Devices.Radios.Radio]]
    $status = [Windows.Devices.Radios.RadioAccessStatus]
    $null   = [Windows.Devices.Radios.Radio,Windows.System.Devices,ContentType=WindowsRuntime]
    $null   = Await -task $radio::RequestAccessAsync() -type $status
    $radios = Await -task $radio::GetRadiosAsync() -type $rList
    
    $wifi   = $radios | where {$_.Kind -eq 'WiFi'}
    $null   = Await -task $wifi.SetStateAsync($newStatus) -type $status
    
    # $bt   = $radios | where {$_.Kind -eq 'Bluetooth'}
    # $null = Await -task $bt.SetStateAsync($newStatus) -type $status
    

    Explanation of the Code Logic

    1. Setting the Desired Status:

      • The $newStatus variable is set to 'On' or 'Off' to indicate whether the radio (WiFi/Bluetooth) should be enabled or disabled.
    2. Loading Required Assemblies:

      • The script loads the System.Runtime.WindowsRuntime assembly, which is necessary for accessing WinRT APIs.
    3. Finding the AsTask Method:

      • The AsTask method converts asynchronous operations (IAsyncOperation<T> in WinRT) into .NET Task objects. The script dynamically identifies the correct overload of AsTask using reflection.
    4. Handling Asynchronous Tasks with Await:

      • Since WinRT APIs return asynchronous operations, the script defines an await function that:
        • Uses the AsTask method to convert a WinRT asynchronous operation into a .NET Task.
        • Waits for the task to complete using .Wait().
        • Retrieves the task result, enabling synchronous handling of asynchronous operations in PowerShell.
    5. Requesting Radio Access:

      • The script first calls RequestAccessAsync to request permission for managing radios.
    6. Retrieving and Managing Radios:

      • The GetRadiosAsync method retrieves a list of radios (WiFi, Bluetooth, etc.) available on the system.
      • The script filters this list based on the Kind property to identify the desired radio (WiFi or Bluetooth).
      • The SetStateAsync method is invoked with the desired state ('On' or 'Off') to toggle the radio.

    Enabling WiFi and Bluetooth


    Asynchronous Handling

    The await function bridges the gap between WinRT's asynchronous operations and PowerShell's synchronous execution model. Here's why this is important:

    1. WinRT APIs Are Asynchronous by Design:

      • Calls like RequestAccessAsync and GetRadiosAsync return IAsyncOperation<T> objects, which cannot be directly awaited in PowerShell.
      • The AsTask method converts these into .NET Task objects, enabling synchronous handling.
    2. Custom await Implementation:

      • The await function uses the identified AsTask method to handle asynchronous operations. It ensures tasks are completed before proceeding, providing a straightforward synchronous experience for the rest of the script.

    This script is an excellent example of how PowerShell can interact with modern WinRT APIs for advanced Windows functionality, such as controlling radios programmatically.