Skip to content

Intune Primary User PR Review

Ed Mozley edited this page Nov 2, 2026 · 1 revision

Assets from their Intune primary user - PR review

PR #236 by vsc55 Β· Follows #235 (review) Β· Verdict: merge

At each Intune sync, an asset nobody holds can be given to its device's primary user in Intune. The PR's branch was cut before #235 was merged, so its own commit was taken across onto main under its author's name; nothing else in the branch was needed. User pages: Assets and Importing people from Entra ID. Internals: Asset reconciliation - Developer Guide Β§6b.

What was checked

Question How Result
Can it pick the wrong person? Read intuneAssignPrimaryUsers(); tests/intune-primary-user.php Matched only by Entra object id: the device's userId against user_sso_identities.source_ref, which only the Entra import fills, on an oidc provider. No name, UPN or email is ever compared. An object id nobody imported assigns nothing
Can it overwrite a person's decision? Read; the test No. Only an asset with no holder is touched; nothing is ever unassigned
What is skipped? Read; the test Leavers, retired assets (assetNotRetiredSql()), a holder in another company, and an asset two devices name two different people for (HAVING COUNT(DISTINCT u.id) = 1)
Does it change anything on upgrade? api/system/db_verify.php, freeitsm.sql No: intune_assign_primary_user is '0' on an upgrade and on a new install - assigning people is the administrator's to switch on
Does one failure stop the sync? Read No: each asset in its own try, counted, logged, and the sync's message says how many could not be assigned
Does the change it carried hold up? The test fails without it Yes - see below

tests/intune-primary-user.php on the test install: 10 checks, all passing, in a transaction that is always rolled back with asset.assigned workflows paused. The asset-retirement, analyst-lifecycle, module-access and escape guards too.

The bug it fixed on the way (#2690)

AssetsService::assignUser() wrote the actor's id straight into users_assets.assigned_by_analyst_id and the custody log. The system actor's id is 0, which the foreign key to analysts refuses - so any automatic assignment, from any caller, would have failed. It now stores NULL, as auditWrite() already did. Worth remembering for any service method that may be called by ActorContext::system(): an actor id of 0 is "nobody", never a foreign key.

What was changed

The changelog rows kept the ids #2689 and #2690 that were reserved for this PR, rewritten as one line each. German and Spanish were added (the PR shipped English only), and the write-up: the Assets page, the Entra import page, the reconciliation developer guide and this page. No code was changed.

Worth knowing

  • It needs the Entra import. People imported from LDAP, CardDAV or typed in have no Entra object id, so they are never matched. That is deliberate: matching by email would bring back exactly the wrong-person risk the object id avoids.
  • It runs inside the Intune sync, after devices are linked to assets - and the Intune sync runs when somebody presses Sync under Assets β†’ Settings β†’ Intune (api/intune/sync.php starts scripts/intune_worker.php). It is not one of the scheduler's jobs, so assets are assigned at the next sync somebody starts, not overnight.
  • source_ref now has two readers. The Entra import writes it and this reads it. Changing what the import stores there would silently stop assets being assigned.

FreeITSM

Getting Started

Modules

Multi-tenancy (planned)

Blue sky thinking

Bugs resolved

Links

Clone this wiki locally