|
#Requires -Version 5.1 |
|
<# |
|
.SYNOPSIS |
|
Remaps the Windows Copilot hardware key to launch ChatGPT Desktop. |
|
|
|
.DESCRIPTION |
|
Uses the native MDM/CSP registry policy (CopilotKey\SetCopilotHardwareKey) |
|
to redirect the Copilot key to the ChatGPT Desktop MSIX app. |
|
Requires ChatGPT to be installed via the MSIX package from the Microsoft Store |
|
or the direct MSIX download from OpenAI. |
|
|
|
You can also change this without the script: open Windows Settings > |
|
Bluetooth & devices > "Customize Copilot key on the keyboard". |
|
|
|
.PARAMETER Revert |
|
Removes the remapping and restores the default Copilot key behavior. |
|
|
|
.NOTES |
|
Install ChatGPT Desktop from the Microsoft Store, or download the MSIX from: |
|
https://openai.com/chatgpt/desktop/ |
|
#> |
|
|
|
[CmdletBinding(SupportsShouldProcess)] |
|
param( |
|
[switch]$Revert |
|
) |
|
|
|
$ErrorActionPreference = 'Stop' |
|
|
|
function Write-Step { |
|
param([string]$Message) |
|
Write-Host "`n==> $Message" -ForegroundColor Cyan |
|
} |
|
|
|
function Write-OK { |
|
param([string]$Message) |
|
Write-Host " [OK] $Message" -ForegroundColor Green |
|
} |
|
|
|
function Write-Fail { |
|
param([string]$Message) |
|
Write-Host " [!!] $Message" -ForegroundColor Red |
|
} |
|
|
|
function Write-Note { |
|
param([string]$Message) |
|
Write-Host " $Message" -ForegroundColor Gray |
|
} |
|
|
|
function Test-Administrator { |
|
$Identity = [Security.Principal.WindowsIdentity]::GetCurrent() |
|
$Principal = New-Object Security.Principal.WindowsPrincipal($Identity) |
|
return $Principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) |
|
} |
|
|
|
function Open-CopilotKeySettings { |
|
Read-Host "`n Press Enter to open the settings page and select ChatGPT (or Ctrl+C to skip)" |
|
Write-Step "Opening Copilot key settings..." |
|
try { |
|
Start-Process "ms-settings:personalization-textinput-copilot-hardwarekey" |
|
Write-OK "Opened Windows Settings > Customize Copilot key on the keyboard." |
|
} catch { |
|
Write-Fail "Could not open Windows Settings automatically: $($_.Exception.Message)" |
|
Write-Note $SettingsHint |
|
} |
|
} |
|
|
|
$RegistryPath = 'HKCU:\SOFTWARE\Policies\Microsoft\Windows\CopilotKey' |
|
$ValueName = 'SetCopilotHardwareKey' |
|
$SettingsHint = "You can also change this in Windows Settings > Bluetooth & devices > `"Customize Copilot key on the keyboard`"." |
|
|
|
# --- Require administrator ---------------------------------------------------- |
|
# The policy lives under HKCU\Software\Policies, whose ACL only grants write to |
|
# SYSTEM and Administrators. Writing it therefore requires an elevated session. |
|
|
|
if (-not (Test-Administrator)) { |
|
Write-Fail "This script must be run as Administrator." |
|
Write-Note "Close this window, right-click PowerShell, choose 'Run as administrator', then re-run the script." |
|
exit 1 |
|
} |
|
|
|
# --- Revert path ------------------------------------------------------------- |
|
|
|
if ($Revert) { |
|
Write-Step "Reverting Copilot key to default behavior..." |
|
|
|
if (-not (Test-Path $RegistryPath)) { |
|
Write-OK "Nothing to revert - no CopilotKey policy is set." |
|
Write-Note $SettingsHint |
|
exit 0 |
|
} |
|
|
|
$Existing = Get-ItemProperty -Path $RegistryPath -Name $ValueName -ErrorAction SilentlyContinue |
|
if ($Existing -and $PSCmdlet.ShouldProcess("$RegistryPath\$ValueName", 'Remove registry value')) { |
|
Remove-ItemProperty -Path $RegistryPath -Name $ValueName |
|
Write-OK "Removed $ValueName." |
|
} else { |
|
Write-OK "No $ValueName value found." |
|
} |
|
|
|
# Remove the key too if it is now empty. |
|
$Remaining = Get-Item -Path $RegistryPath | Select-Object -ExpandProperty Property |
|
if (-not $Remaining -and $PSCmdlet.ShouldProcess($RegistryPath, 'Remove empty registry key')) { |
|
Remove-Item -Path $RegistryPath |
|
Write-OK "Removed empty registry key: $RegistryPath" |
|
} |
|
|
|
Write-Host "`n Reverted. Sign out and back in for the change to take effect." -ForegroundColor Green |
|
Write-Note $SettingsHint |
|
if (-not $WhatIfPreference) { Open-CopilotKeySettings } |
|
exit 0 |
|
} |
|
|
|
# --- Step 1: Find ChatGPT's AUMID -------------------------------------------- |
|
|
|
Write-Step "Locating ChatGPT Desktop MSIX installation..." |
|
|
|
$ChatGPTApps = @(Get-StartApps -Name "ChatGPT" | Where-Object { $_.AppID -like "*!*" }) |
|
|
|
if ($ChatGPTApps.Count -eq 0) { |
|
Write-Fail "ChatGPT Desktop (MSIX) was not found." |
|
Write-Host @" |
|
|
|
The Copilot key remapping requires the MSIX version of ChatGPT Desktop. |
|
Install it from the Microsoft Store, or download the MSIX directly from: |
|
|
|
https://openai.com/chatgpt/desktop/ |
|
|
|
After installing, re-run this script. |
|
"@ -ForegroundColor Yellow |
|
exit 1 |
|
} |
|
|
|
if ($ChatGPTApps.Count -gt 1) { |
|
Write-Note "Found $($ChatGPTApps.Count) ChatGPT entries; using the first:" |
|
foreach ($AppEntry in $ChatGPTApps) { Write-Note " - $($AppEntry.Name): $($AppEntry.AppID)" } |
|
} |
|
|
|
$ChatGPTApp = $ChatGPTApps[0] |
|
$ChatGPTAUMID = $ChatGPTApp.AppID |
|
Write-OK "Found ChatGPT AUMID: $ChatGPTAUMID" |
|
|
|
# Confirm the AUMID resolves to an installed MSIX package (not a stale Start entry). |
|
$PackageFamily = ($ChatGPTAUMID -split '!')[0] |
|
$Package = Get-AppxPackage | Where-Object { $_.PackageFamilyName -eq $PackageFamily } |
|
|
|
if (-not $Package) { |
|
Write-Fail "The Start menu entry exists but no matching MSIX package is installed." |
|
Write-Note "Reinstall ChatGPT Desktop and re-run this script." |
|
exit 1 |
|
} |
|
Write-OK "Confirmed installed MSIX package: $($Package.Name)" |
|
|
|
# --- Step 2: Write registry policy ------------------------------------------- |
|
|
|
Write-Step "Configuring CopilotKey registry policy..." |
|
|
|
if (-not (Test-Path $RegistryPath)) { |
|
if ($PSCmdlet.ShouldProcess($RegistryPath, 'Create registry key')) { |
|
New-Item -Path $RegistryPath -Force | Out-Null |
|
Write-OK "Created registry key: $RegistryPath" |
|
} |
|
} else { |
|
Write-OK "Registry key already exists: $RegistryPath" |
|
} |
|
|
|
if ($PSCmdlet.ShouldProcess("$RegistryPath\$ValueName", "Set value to '$ChatGPTAUMID'")) { |
|
Set-ItemProperty -Path $RegistryPath -Name $ValueName -Value $ChatGPTAUMID -Type String |
|
Write-OK "Set $ValueName = $ChatGPTAUMID" |
|
} |
|
|
|
# --- Step 3: Verify ---------------------------------------------------------- |
|
|
|
Write-Step "Verifying registry entry..." |
|
|
|
$VerifyValue = Get-ItemPropertyValue -Path $RegistryPath -Name $ValueName -ErrorAction SilentlyContinue |
|
|
|
if ($VerifyValue -eq $ChatGPTAUMID) { |
|
Write-OK "Verification passed." |
|
Write-Host "`n ChatGPT is now available as a Copilot key option." -ForegroundColor Green |
|
Write-Note "To finish, select ChatGPT under `"Customize Copilot key on the keyboard`" - the settings page opens next." |
|
Write-Note "If the option or the key change does not take effect, restart Explorer to reload the shell:" |
|
Write-Note " Stop-Process -Name explorer -Force (Explorer restarts automatically)" |
|
Write-Note "or sign out and back in." |
|
Write-Host "" |
|
Open-CopilotKeySettings |
|
} elseif ($WhatIfPreference) { |
|
Write-Note "Skipped verification (-WhatIf)." |
|
} else { |
|
Write-Fail "Verification failed - the registry value does not match. Please check manually." |
|
exit 1 |
|
} |
Can confirm this works! I ran the script, and pressing my Copilot key now opens the new ChatGPT app instead of Classic.
One small downside: my customization dropdown now only shows Search and ChatGPT, so I lost the other options. Just something to keep in mind if you want to try this.
Hopefully OpenAI adds proper support for this soon so we won't need workarounds like this.