<# .SYNOPSIS Make Chrome the default browser and pin it to the taskbar, as far as Windows permits that from a script. .DESCRIPTION Which is not very far, and it is worth knowing why before reading the code. The default-browser association lives under UserChoice, whose ProgId is validated against a hash Windows will only generate from its own Settings dialog — and since February 2024 a kernel driver (UCPD.sys) blocks writes to that key regardless. Tools that forge the hash exist; they are working around a security control and Microsoft breaks them on a schedule. Taskbar pinning lost its shell verb years ago for the same reason: to stop installers helping themselves to the taskbar. What is supported is policy, and policy applies when a user profile is created — so both settings here take effect for the NEXT new user to sign in, not for the profile running this. For the current profile the honest answers are a desktop shortcut, which this makes, and two clicks in Settings, which this opens for you. Needs elevation: both policies are machine-wide. .EXAMPLE powershell -NoProfile -ExecutionPolicy Bypass -File scripts\configure-chrome-defaults.ps1 #> [CmdletBinding()] param( # Skip opening the Settings page at the end. [switch]$Quiet ) $ErrorActionPreference = 'Stop' $identity = [Security.Principal.WindowsIdentity]::GetCurrent() if (-not ([Security.Principal.WindowsPrincipal]$identity).IsInRole( [Security.Principal.WindowsBuiltInRole]::Administrator)) { throw 'Run this elevated — both policies are machine-wide.' } $chrome = @("$env:ProgramFiles\Google\Chrome\Application\chrome.exe", "${env:ProgramFiles(x86)}\Google\Chrome\Application\chrome.exe", "$env:LOCALAPPDATA\Google\Chrome\Application\chrome.exe") | Where-Object { $_ -and (Test-Path $_) } | Select-Object -First 1 if (-not $chrome) { throw 'Google Chrome is not installed.' } $dir = Join-Path $env:ProgramData 'AutoFirmer' New-Item -ItemType Directory -Path $dir -Force | Out-Null # ── Default browser ───────────────────────────────────────────────────────── # Only the associations named here are overridden; everything absent from the # file keeps whatever Windows would have chosen. $assoc = Join-Path $dir 'default-associations.xml' @' '@ | Set-Content -Path $assoc -Encoding UTF8 $sys = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\System' if (-not (Test-Path $sys)) { New-Item -Path $sys -Force | Out-Null } New-ItemProperty -Path $sys -Name 'DefaultAssociationsConfiguration' ` -Value $assoc -PropertyType String -Force | Out-Null Write-Host "Default-browser policy written: $assoc" # ── Taskbar pin ───────────────────────────────────────────────────────────── # A taskbar layout with no start layout beside it: the collection below adds the # pin, and PinListPlacement="Replace" would wipe the user's own pins, so it is # deliberately absent — ours is appended to whatever is already there. $lnk = Join-Path $dir 'Google Chrome.lnk' $shell = New-Object -ComObject WScript.Shell $shortcut = $shell.CreateShortcut($lnk) $shortcut.TargetPath = $chrome $shortcut.Save() $taskbar = Join-Path $dir 'TaskbarLayoutModification.xml' @" "@ | Set-Content -Path $taskbar -Encoding UTF8 $explorer = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\Explorer' if (-not (Test-Path $explorer)) { New-Item -Path $explorer -Force | Out-Null } New-ItemProperty -Path $explorer -Name 'StartLayoutFile' -Value $taskbar -PropertyType ExpandString -Force | Out-Null # 0 so the Start menu itself stays the user's to rearrange; only the taskbar # collection above is applied. New-ItemProperty -Path $explorer -Name 'LockedStartLayout' -Value 0 -PropertyType DWord -Force | Out-Null Write-Host "Taskbar pin policy written: $taskbar" # ── The current profile ───────────────────────────────────────────────────── $desktop = [Environment]::GetFolderPath('CommonDesktopDirectory') $deskLnk = $shell.CreateShortcut((Join-Path $desktop 'Google Chrome.lnk')) $deskLnk.TargetPath = $chrome $deskLnk.Save() Write-Host 'Desktop shortcut created.' Write-Host @' Both policies apply when a user profile is first created, so this profile is unchanged. For this one: * Default browser: the Settings page is opening now - pick Google Chrome under "Web browser". Windows allows no other way. * Taskbar: right-click Chrome and choose "Pin to taskbar". '@ if (-not $Quiet) { Start-Process 'ms-settings:defaultapps' }