Turn on/off Bluetooth radio/adapter from cmd/powershell in Windows 10

29

8

Such a simple task, one would say, and I haven't found a satisfiable solution. What I've tried (with music playing through a Bluetooth-connected speaker to really know the state of the radio):

  • using devcon as admin: devcon disable USB\VID_8087&PID_07DC&REV_0001 (which is the HW ID of my Bluetooth adapter)... requires reboot to work...
  • using powershell as admin: Disable-NetAdapter "Bluetooth Network Connection 3" (which is translation of the name of my Bluetooth adapter)... it disables the PAN driver, but a Bluetooth speaker continues playing music...
  • using net as admin: net stop bthserv... doesn't actually turn off the radio (BT speaker continues playing music)
  • using .NET: The most relevant page on MSDN doesn't say a word about turning the adapter on/off.
  • using explorer: ms-settings:bluetooth or explorer.exe %LocalAppData%\Packages\windows.immersivecontrolpanel_cw5n1h2txyewy\LocalState\Indexed\Settings\cs-CZ\AAA_SettingsPagePCSystemBluetooth.settingcontent-ms... opens the Bluetooth settings panel, but I still have to click on the toggle

I can't believe Microsoft would be so ignorant to not provide such a command...

Martin Pecka

Posted 2017-01-17T23:19:20.253

Reputation: 643

How are you playing the music? – harrymc – 2018-02-04T20:33:00.943

Using Winamp :) – Martin Pecka – 2018-02-04T21:04:15.353

Does killing Winamp stop the music? – harrymc – 2018-02-04T21:57:21.067

Of course, why it wouldn't? But the question is not about stopping music playback, it is about control of the BT radio. – Martin Pecka – 2018-02-04T23:20:01.210

You can't stop the music by disabling the device. You don't want to stop the play by the program. So all you have left is to mute the device. Would that be a solution? – harrymc – 2018-02-05T08:39:03.377

2@harrymc Read the question, please. Music playback is just a way how I detect if the Bluetooth connection is alive or not. What I'm really interested in is really a way to disable/enable the Bluetooth adapter. – Martin Pecka – 2018-02-05T09:31:42.913

Answers

22

This is challenging because of the necessary interoperation with WinRT, but it is possible in pure PowerShell:

[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

To use it, save it is a PS1 file, e.g. bluetooth.ps1. If you haven't already, follow the instructions in the Enabling Scripts section of the PowerShell tag wiki to enable the execution of scripts on your system. Then you can run it from a PowerShell prompt like this:

.\bluetooth.ps1 -BluetoothStatus On

To turn Bluetooth off, pass Off instead.

To run it from a batch file:

powershell -command .\bluetooth.ps1 -BluetoothStatus On

Caveat: If the Bluetooth Support Service is not running, the script attempts to start it because otherwise, WinRT will not see Bluetooth radios. Alas, the service cannot be started if the script is not running as administrator. To make that unnecessary, you can change the startup type of that service to automatic.

Now for some explanation. The first three lines establish the parameters the script takes. Before beginning in earnest, we make sure the Bluetooth Support Service is running and start it if not. We then load the System.Runtime.WindowsRuntime assembly so that we can use the WindowsRuntimeSystemExtensions.AsTask method to convert WinRT-style tasks (which .NET/PowerShell doesn't understand) to .NET Tasks. That particular method has a boatload of different parameter sets which seem to trip up PowerShell's overload resolution, so in the next line we get the specific one that takes only a resultful WinRT task. Then we define a function that we'll use several times to extract a result of the appropriate type from an asynchronous WinRT task. Following that function's declaration, we load two necessary types from WinRT metadata. The remainder of the script is pretty much just a PowerShell translation of the C# code you wrote in your answer; it uses the Radio WinRT class to find and configure the Bluetooth radio.

Ben N

Posted 2017-01-17T23:19:20.253

Reputation: 32 973

1You cannot call a method on a null-valued expression. At C:\Users\chx\AppData\Local\Microsoft\WindowsApps\bluetooth.ps1:18 char:1

  • Await ($bluetooth.SetStateAsync($BluetoothStatus)) ([Windows.Devices.
  • < – chx – 2018-02-09T03:45:17.353

@chx Are you sure your machine has a Bluetooth adapter? If there is no Bluetooth radio, the third-to-last line will set $bluetooth to null, which will cause the second-to-last line to produce that error. – Ben N – 2018-02-09T03:46:56.290

I am 100% sure it's visible in the "Settings" app and I listen music wirelessly and both Device Manager and wmic also reports it. – chx – 2018-02-09T03:47:34.087

@chx Hmm, what do you get if you replace the last three lines with just $radios? That will show the list of radios that WinRT returned. – Ben N – 2018-02-09T03:49:45.630

@chx Ah, I found the problem. The Bluetooth Support Service must be running for the WinRT API to see Bluetooth radios. Somehow it gets triggered to start if the normal Settings app is used (possibly even without the user being an admin?), but I've added a line that makes sure it's running and starts it via the normal mechanism if not. This requires admin privileges, but it consistently works. Thanks for the note! – Ben N – 2018-02-09T04:16:02.403

$radios only has WiFi Wi-Fi On. This is in an Administrator PowerShell. bthserv is running. I am on 64 bit Windows 10, latest. – chx – 2018-02-09T06:02:05.627

@chx If you remove the | Out-Null on the line that includes RequestAccessAsync, what does it print? It should be Allowed. Also, does anything change for the better if you run the script from an x86 PowerShell process? – Ben N – 2018-02-09T13:57:39.767

2Clever, it works! I just couldn't get to compile a desktop app using this API, but loading it dynamically in a script seems to be the way to go. Now, compare to rfkill unblock bluetooth on Linux :-D – Martin Pecka – 2018-02-10T00:30:38.697

@BenN yes, it says Allowed. – chx – 2018-02-10T00:41:57.080

@chx Hmm, what brand/model is your Bluetooth adapter? You can get that information from Device Manager. At least with other APIs, there seems to be some variance as to whether a manufacturer's devices will be listed. Also, there are non-WinRT ways of getting at this info, such as a native API, but that function unhelpfully omits radios that are turned off.

– Ben N – 2018-02-10T00:44:24.767

@BenN USB\VID_8087&PID_0A2B. . Intel Wireless Bluetooth 8265. – chx – 2018-02-10T00:49:33.263

@chx Strange, I have an extremely similar Intel Bluetooth device in my laptop. This is kind of a long shot, but does trying to update the driver for the device in Device Manager change anything? And though you've probably tried this already, does a reboot change anything? – Ben N – 2018-02-11T16:21:01.080

Thanks for the solution. It's working great on my Win 10.0.17134 .0 – Atiq Rahman – 2018-05-06T05:12:53.983

@BenN By chance, do you know how to reconnect a bluetooth hardware that has been disconnected using Disable/Enable-NetAdapter? https://superuser.com/questions/1444278/windows-10-disable-netadapter-disconnect-the-hardware-blutooth-from-the-compu

– JinSnow – 2019-06-03T11:28:30.670

To adapt this script so that it itself checck if the bluetooth is on (or off) and the stop it (or start it) see https://superuser.com/q/1494499

– MagTun – 2019-10-24T06:12:06.250

5

After giving up to seek for ready-made solutions, I've found out that the Universal Windows Platform apps have access to the radio control API.

So I merged a sample radio control app with a commandline-controlled app, and the result is here: https://github.com/peci1/RadioControl . It's published on Windows Store.

In general, it isn't possible to just let the app run in background, so you need to first launch the GUI, and then you can call it from the commandline like

radiocontrol.exe 0 on
radiocontrol.exe Bluetooth off

The core features that this app needs are:

using Windows.Devices.Radios;
await Radio.RequestAccessAsync();
var radios = await Radio.GetRadiosAsync();
await radios[0].SetStateAsync(RadioState.On);

Then you also need to add the Radios capability to the app manifest:

<DeviceCapability Name="radios" />

And to allow control from commandline, you need to override method protected override async void OnActivated(IActivatedEventArgs args) in App.xaml.cs and do the processing in a branch like this:

switch (args.Kind)
        {
            case ActivationKind.CommandLineLaunch:

Martin Pecka

Posted 2017-01-17T23:19:20.253

Reputation: 643

This answer better fits StackOverflow. – harrymc – 2018-02-05T11:40:17.590

@MartinPecka By chance, do you know how to reconnect Bluetooth hardware that has been disconnected using Disable/Enable-NetAdapter? https://superuser.com/questions/1444278/windows-10-disable-netadapter-disconnect-the-hardware-blutooth-from-the-compu

– JinSnow – 2019-06-03T11:29:45.957

3

This Autohotkey script seems to do the trick. I am bothered by the Sleep there but it seems the window becomes active before it is ready to receive my keystrokes.

SendMode Input
Run, ms-settings:bluetooth
WinWaitActive, Settings
Sleep 300
Send,{Tab}{Space}
WinClose, A

Crossposted to https://stackoverflow.com/q/48700268/308851 to figure out what that Sleep 300 could be replaced with.

chx

Posted 2017-01-17T23:19:20.253

Reputation: 3 069

This could also be a solution in most cases. I needed to also add a short sleep after sending the keystrokes. And this solution doesn't work if the screen is locked. The Universal Windows app I posted above does work even with locked screen. – Martin Pecka – 2018-02-09T15:00:21.063

2

Here's a partial solution: wmic path Win32_PNPEntity where "caption like '%bluetooth%' AND DeviceID like 'USB\\%'" call disable certainly makes the Bluetooth On/Off switch disappear and Device Manager reports This device is disabled. (Code 22). Whether that's enough to kill the radio, I am not sure.

I am unable to find documentation on what arguments call accepts. I think there should be some sort of rfkill here.

chx

Posted 2017-01-17T23:19:20.253

Reputation: 3 069

I'm sorry, doesn't work for me as you describe it. For me, the Bluetooth playback stops, but all the bluetooth switches in control panel remain on. And calling with enable doesn't resume the Bluetooth playback. The documentation on the PNPEntity class is here: https://msdn.microsoft.com/en-us/library/aa394353(v=vs.85).aspx , but no other useful methods seem to be there...

– Martin Pecka – 2018-02-04T17:43:34.153

1

You can use DevManView to enable/disable a device from the command line using this syntax:

devmanview /disable <Device Name>   
devmanview /enable <Device Name>    

It also allows the use of wildcards with the /use_wildcard argument.

rahuldottech

Posted 2017-01-17T23:19:20.253

Reputation: 5 095

Devmanview is indeed a useful tool, but it doesn't solve my problem. The problem is that there doesn't seem to be a device which you could disable in device manager to turn off the bluetooth radio. – Martin Pecka – 2018-02-10T00:03:07.953

@MartinPecka Do you not see any of these? https://i.stack.imgur.com/UrOuc.png If not, you might want to try and update drivers...

– rahuldottech – 2018-02-10T08:52:33.800

I do see the Bluetooth device, but disabling it doesn't stop the playback - probably because the system needs to be restarted for it to really become disabled (as stated in the original question). – Martin Pecka – 2018-02-10T17:19:44.413

0

Powershell has cmdlets for doing exactly what you're seeking:

https://gallery.technet.microsoft.com/PowerShell-Device-60d73bb0

Use Get-Device to get a list of the devices. You can pipe that through where-object to pick your device and then pipe that to Disable-Device or Enable-Device.

Detailed Instructions...

Download and unzip the file.

Start a powershell as admin.

Change execution policy if necessary:

Set-ExecutionPolicy Unrestricted

Import the module:

Import-Module .\DeviceManagement.psd1

If you need to narrow down the list of devices you can use a -like compare:

Get-Device | Where-Object {$_.Name -like '*bluetooth*'}

If you know the exact name you can use an -eq (equals) compare:

Get-Device | Where-Object {$_.Name -eq 'Martin's Bluetooth Adapter'} | Disable-Device -Confirm:$False

Wipe hands on pants.

apocalysque

Posted 2017-01-17T23:19:20.253

Reputation: 583

This will disable the USB device instead of just the radio. wmic can do this too, at least I think so. – chx – 2018-02-09T03:39:27.787

The question didn't ask how to disable to radio but not the adapter. Why the distinction? If you can give me a good reason I'll consider digging for you, but I answered the question that was asked "What I'm really interested in is really a way to disable/enable the Bluetooth adapter. – Martin Pecka Feb 5 at 9:31" – apocalysque – 2018-02-09T04:04:38.167

I'm sorry, what's the difference between adapter and radio? I consider these two terms equivalent. There's a ***load of software devices this HW thing provides, and you're right this question is not about them. – Martin Pecka – 2018-02-10T00:06:21.230

Moreover, both this and the 2012 PS script from Ricardo Mendes do not work at my Win 10 1709 64bit, as is mentioned in their comments. Both end up with error Disable-Device : Error calling SetupDiCallClassInstaller. I run them as admin and with unrestricted execution policy. – Martin Pecka – 2018-02-10T00:22:18.480

0

I made a batch script that checks a reg key value which would only be in place if your bluetooth radio was enabled. It then calls Ben N's powershell script above with the correct parameter to switch its current state. Turns it into a toggle shortcut, rather than having to use on and off separately.

@echo off
FOR /F "skip=2 tokens=2,*" %%A IN ('reg.exe query "HKLM\SYSTEM\CurrentControlSet\Services\bthserv\Parameters\BluetoothControlPanelTasks" /v "state"') DO set "VAR=%%B"

if %VAR%==0x1 (goto ON)

Powershell.exe -executionpolicy remotesigned -windowstyle hidden -File ".\bluetooth.ps1" -BluetoothStatus On
goto end

:ON
Powershell.exe -executionpolicy remotesigned -windowstyle hidden -File ".\bluetooth.ps1" -BluetoothStatus Off

:end

007craft

Posted 2017-01-17T23:19:20.253

Reputation: 11

-1

Executing the following command from Command Prompt (as administrator) did the trick:

netsh interface set interface name="Bluetooth Network Connection" admin=disabled

I had previously used the same command to disable my Wi-Fi adapter, and found that it also worked with the other adapters in: Control Panel > Network and Internet > Network Connections. Just change the "name" argument to the name of your adapter. You can also enable it again by changing the last argument to admin=enabled.

Micah Vertal

Posted 2017-01-17T23:19:20.253

Reputation: 101

1This also seems to just disable the PAN drivers, but doesn't turn off the radio device itself (in control panel, Bluetooth is still being reported as "on"). – Martin Pecka – 2017-07-05T23:57:14.413

Verified now by the bluetooth repro test, doesn't turn off bluetooth. – Martin Pecka – 2017-07-06T21:43:18.570

I'm sorry @peci1 , I misunderstood your question. I had previously been looking at questions relating to disabling Bluetooth and interpreted your question as the same. So your goal is to turn off (cut power to) the Bluetooth device? I will research a bit and let you know if I find anything. – Micah Vertal – 2017-07-07T02:33:44.490

@peci1 would this link be helpful at all?

– Micah Vertal – 2017-07-16T22:09:51.487

No, it does not. It's about USB, not Bluetooth devices. And the linked Device Management Cmdlet doesn't work, either. – Martin Pecka – 2017-08-30T01:18:04.497