The managed-machine rule is Chromium's, not Edge's

Chrome blanks an off-store ExtensionInstallForcelist entry on an unmanaged
machine exactly as Edge does - the qualifying states are AD domain join, Entra
join, or Chrome Enterprise Core enrolment, and this box is none of them. The
guard now covers every browser and refuses up front, with the three ways
forward, instead of skipping Edge alone and letting Chrome fail the same way.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Brandon Li
2026-08-31 13:30:04 -05:00
co-authored by Claude Opus 5
parent e42e729189
commit ce6fa6c0e1
3 changed files with 71 additions and 33 deletions
+35 -17
View File
@@ -95,15 +95,20 @@ function Test-BrowserInstalled([string]$Name) {
}
<#
Edge refuses to install an extension it did not get from the Microsoft Store
unless the device is managed — domain-joined, Intune-enrolled or Entra-joined.
The policy is read and then blanked: edge://policy shows the value as
"[BLOCKED]..." with "This device isn't managed by your organization", and an
"Invalid extension ID" error from parsing that prefix.
The restriction that decides whether any of this works.
Chrome and Brave have no such restriction. So on an unmanaged machine there
is nothing to be gained by writing Edge's key, and a real cost: Edge starts
reporting "Managed by your organization" and shows a policy error forever.
On Windows, Chromium will only force-install an extension from outside its
own web store when the instance is joined to an Active Directory domain,
joined to Entra ID, or enrolled in Chrome Enterprise Core (what used to be
called Chrome Browser Cloud Management). Edge says the same thing about the
Microsoft Store. On anything else the policy is read and then blanked:
chrome://policy shows "[BLOCKED]<id>;<url>" and an "Invalid extension ID"
error, because the [BLOCKED] prefix is what gets parsed as the id.
This is not something the update server can work around — it is about the
machine, not the extension, the hive, or the browser. So rather than leave a
permanent policy error and a "Managed by your organization" badge behind for
nothing, this refuses up front and says what the ways round it are.
#>
function Test-DeviceManaged {
try {
@@ -136,18 +141,31 @@ if (-not $targets) {
throw 'Found no Chrome, Edge or Brave installation. Name one with -Browser to configure it regardless of what this can see.'
}
if (-not $Remove -and ($targets -contains 'Edge') -and -not $Force -and -not (Test-DeviceManaged)) {
if (-not $Remove -and -not $Force -and -not (Test-DeviceManaged)) {
Write-Warning @'
Edge is skipped: this device is not managed (not domain-joined, Intune-enrolled
or Entra-joined), and unmanaged Edge only installs extensions from the Microsoft
Store. It would read the policy and blank the value.
This machine is not enterprise managed - not domain-joined, not Entra-joined,
not enrolled in Chrome Enterprise Core - and no Chromium browser will
force-install an extension from outside its own web store on such a machine.
The policy would be read and blanked. Nothing was written.
Use Chrome or Brave for the update-server install, or load extension\ unpacked
in Edge - an unpacked copy still reloads itself when the dashboard reports a
newer version. -Force writes the key anyway.
Three ways forward:
1. Load extension\ unpacked. It has no update channel, but it reloads itself
from disk whenever the dashboard reports a newer version, and the updater
has already pulled those files. Works today, on any browser.
2. Enrol Chrome in Chrome Enterprise Core (free). One registry value -
CloudManagementEnrollmentToken - makes the browser managed, after which
this script works exactly as intended and the update server needs no
changes.
3. Publish the extension to a web store. Store-hosted extensions update
themselves with no policy at all.
-Force writes the policy anyway, if you know this machine is managed and
dsregcmd simply cannot see it.
'@
$targets = @($targets | Where-Object { $_ -ne 'Edge' })
if (-not $targets) { exit 1 }
exit 1
}
Write-Host "Configuring: $($targets -join ', ')"