Skip to content

Instantly share code, notes, and snippets.

@Lilleengen
Created September 3, 2023 12:56
Show Gist options
  • Save Lilleengen/e746ac3e6b563fb88139871af997017f to your computer and use it in GitHub Desktop.
Save Lilleengen/e746ac3e6b563fb88139871af997017f to your computer and use it in GitHub Desktop.
Powershell script that gives you a systray icon to enble or disable bluetooth devices on Windows. Helps provent Windows from interfering with other devices using headphones.
$allBluetoothDevices = Get-PnpDevice -Class Bluetooth
$devicesByContainerId = @{}
foreach ($device in $allBluetoothDevices) {
$deviceProperties = Get-PnpDeviceProperty -InstanceId $device.InstanceId
$containerId = $deviceProperties | Where-Object { $_.KeyName -eq "DEVPKEY_Device_ContainerId" } | Select -ExpandProperty "Data"
if (-Not ($devicesByContainerId[$containerId])) {
$devicesByContainerId.add($containerId, @())
}
$devicesByContainerId[$containerId] += $device.InstanceId
}
$nameByContainerId = @{}
foreach($containerId in $devicesByContainerId.keys) {
$names = @()
foreach($instanceId in $devicesByContainerId[$containerId]) {
$names += $allBluetoothDevices | Where-Object { $_.InstanceId -eq $instanceId } | Select -ExpandProperty "FriendlyName"
}
$shortestName = $names | Sort-Object Length | Select -First 1
$nameByContainerId.add($containerId, $shortestName)
}
$statusByContainerId = @{}
foreach($containerId in $devicesByContainerId.keys) {
$firstInstanceId = $devicesByContainerId[$containerId][0]
$status = $allBluetoothDevices | Where-Object { $_.InstanceId -eq $firstInstanceId } | Select -ExpandProperty "Status"
$statusByContainerId.add($containerId, $status)
}
[System.Reflection.Assembly]::LoadWithPartialName('System.Drawing') | out-null
[System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms') | out-null
$icon = [System.Drawing.Icon]::ExtractAssociatedIcon("C:\Windows\System32\fsquirt.exe")
# Add the systray icon
$Main_Tool_Icon = New-Object System.Windows.Forms.NotifyIcon
$Main_Tool_Icon.Text = "Disable bluetooth devices"
$Main_Tool_Icon.Icon = $icon
$Main_Tool_Icon.Visible = $true
$menuItems = @()
$enableDisable = @{}
$order = [string[]] $devicesByContainerId.keys
foreach($containerId in $order) {
$menuItem = New-Object System.Windows.Forms.MenuItem
$enableDisable.add($containerId, $menuItem)
$isEnabled = $statusByContainerId[$containerId] -eq "OK"
$index = $order.IndexOf($containerId)
$enableDisable[$containerId].Index = $index
if ($isEnabled) {
$enableDisable[$containerId].Text = $nameByContainerId[$containerId]
} else {
$enableDisable[$containerId].Text = "[DISABLED] " + $nameByContainerId[$containerId]
}
$menuItems += $enableDisable[$containerId]
$enableDisable[$containerId].add_Click({
param (
[object] $sender,
[System.EventArgs] $e
)
process {
$id = $order[$sender.Index]
$isEnabled = $statusByContainerId[$id] -eq "OK"
if ($isEnabled) {
foreach($instanceId in $devicesByContainerId[$id]) {
Disable-PnpDevice -InstanceId $instanceId -Confirm:$false
}
$enableDisable[$id].Text = "[DISABLED] " + $nameByContainerId[$id]
$statusByContainerId[$id] = "Error"
} else {
foreach($instanceId in $devicesByContainerId[$id]) {
Enable-PnpDevice -InstanceId $instanceId -Confirm:$false
}
$enableDisable[$id].Text = $nameByContainerId[$id]
$statusByContainerId[$id] = "OK"
}
}
})
}
# Add menu exit
$Menu_Exit = New-Object System.Windows.Forms.MenuItem
$Menu_Exit.Text = "Exit"
$menuItems += $Menu_Exit
# Add all menus as context menus
$contextmenu = New-Object System.Windows.Forms.ContextMenu
$Main_Tool_Icon.ContextMenu = $contextmenu
$Main_Tool_Icon.contextMenu.MenuItems.AddRange($menuItems)
$Menu_Exit.add_Click({
$Main_Tool_Icon.Visible = $false
$window.Close()
Stop-Process $pid
})
# Make PowerShell Disappear
$windowcode = '[DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);'
$asyncwindow = Add-Type -MemberDefinition $windowcode -name Win32ShowWindowAsync -namespace Win32Functions -PassThru
$null = $asyncwindow::ShowWindowAsync((Get-Process -PID $pid).MainWindowHandle, 0)
# Force garbage collection just to start slightly lower RAM usage.
[System.GC]::Collect()
$appContext = New-Object System.Windows.Forms.ApplicationContext
[void][System.Windows.Forms.Application]::Run($appContext)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment