Bluetooth Reset Script in Powershell

I recently had a need to be able to reset Bluetooth from a Powershell script. I found a lovely little script at https://techcommunity.microsoft.com/t5/windows-powershell/switch-bluetooth-off-and-on-via-powershell/m-p/2275616 that neatly fit the bill.

But there was a little more to it. It had to run based on a Windows event. I needed the script to run when I opened my laptop to run the reset. With a little investigation, I found that using Task Scheduler to trigger on an Event ID in Windows of 107 when Windows wakes up from sleeping. I had found my trigger event.

The entire script and task manager setup was cobbled together in about half and hour and works fine for my purposes. All the essentials are noted below with code to scrape and an example of the trigger in Windows Task Manager.

Enjoy!

Triggering the script to run on Event 107

 

Adding the trigger

Bluetooth Reset Script

# bluetooth.ps1
# Turn bluetooth on or off from Powershell.
#
# Usage:
#
# .\bluetooth.ps1 -BluetoothStatus On
# .\bluetooth.ps1 -BluetoothStatus Off
#
[CmdletBinding()] Param (
[Parameter(Mandatory=$true)][ValidateSet(‘Off’, ‘On’)][string]$BluetoothStatus
)
If ((Get-Service bthserv).Status -eq ‘Stopped’) { Start-Service bthserv }
Add-Type -AssemblyName System.Runtime.WindowsRuntime
$asTaskGeneric = ([System.WindowsRuntimeSystemExtensions].GetMethods() | ? { $_.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
$netTask.Result
}
[Windows.Devices.Radios.Radio,Windows.System.Devices,ContentType=WindowsRuntime] | Out-Null
[Windows.Devices.Radios.RadioAccessStatus,Windows.System.Devices,ContentType=WindowsRuntime] | Out-Null
Await ([Windows.Devices.Radios.Radio]::RequestAccessAsync()) ([Windows.Devices.Radios.RadioAccessStatus]) | Out-Null
$radios = Await ([Windows.Devices.Radios.Radio]::GetRadiosAsync()) ([System.Collections.Generic.IReadOnlyList[Windows.Devices.Radios.Radio]])
$bluetooth = $radios | ? { $_.Kind -eq ‘Bluetooth’ }
[Windows.Devices.Radios.RadioState,Windows.System.Devices,ContentType=WindowsRuntime] | Out-Null
Await ($bluetooth.SetStateAsync($BluetoothStatus)) ([Windows.Devices.Radios.RadioAccessStatus]) | Out-Null

The Calling Script

This script is called from the Task Scheduler when the trigger is activated.

# ResetBluetooth.ps1
# Written September 2022
# Jon F. ALmada
#
# Query to see if we reset the Bluetooth services or not.
[System.Reflection.Assembly]::LoadWithPartialName(“System.Windows.Forms”)
$result = [System.Windows.Forms.MessageBox]::Show(‘Reset Bluetooth (Y/N)’ , “Info” , 4)

if ($result -eq “Y”) {
# Reset Bluetooth Connection on startup from sleep
.\bluetooth.ps1 -BluetoothStatus Off
.\bluetooth.ps1 -BluetoothStatus On
break
}
exit