Microsoft Intune · Microsoft Graph · Blazor Server · .NET · Scope Tags
Intune Tag Manager: bulk scope tags as background jobs
Follow bulk scope-tag work as a background job, including Graph throttling, partial results and the limits of an in-memory queue.
- Drafted
- Published
- Updated
- Reading time
- 3 min
- Author
- Roberto Gramellini
Source:
Intune.TagManager
· revision 8f266284
- Intune Tag Manager
- Intune scope tags
- Graph API batch
- SignalR job progress
- Intune bulk operations
Intune Tag Manager: bulk scope tags as background jobs
Assigning a few scope tags is easy enough. Once the list gets large, I want to know more than whether the button was clicked. How much has finished? Which objects failed? Is Graph throttling the work, or has something stopped?
Intune.TagManager handles these larger Scope Tag operations in a Blazor Server application. The web layer creates a job and puts it in an in-process channel. A background worker does the work, with progress sent back through the application and SignalR. The browser does not have to hold one request open until the last Graph call finishes.
Give the operation a job number
A job identifier gives the operator something to follow after submitting the update. The interface can report how many items were processed, succeeded or failed while execution continues. Unlike some office paperwork, the number here is meant to help you find out what is actually happening.
The code is split into a Core library with shared models and Graph services, a Worker, and the Blazor Server UI/API. Scope-tag assignments and report generation use the same executor contract. The worker reads a channel request, updates the job state and forwards progress callbacks to the SignalR hub.
Code excerpt: queue work for one background consumer
The queue setup and enqueue operation are small. This is the relevant excerpt from JobChannel.cs.
_channel = Channel.CreateUnbounded<JobRequest>(new UnboundedChannelOptions { SingleReader = true, SingleWriter = false }); public async ValueTask EnqueueAsync(JobRequest request, CancellationToken ct = default) { await _channel.Writer.WriteAsync(request, ct); }
Multiple producers can write to the unbounded channel; SingleReader fits the one background consumer. It is simple, but be clear about what you have bought: the queue lives in the process. It is not a durable broker, and there is no queue-length backpressure here. Review restart behaviour before treating an accepted job as work that is safely stored.
Graph batching is an optimization, not a transaction
For bulk device lookups, the Graph service groups identifiers according to the configured request limit and submits a $batch request. It reads the individual statuses and can retry just the throttled subrequests, leaving successful items alone. The README gives a maximum batch size of 20, in line with Graph's limit. Check the configuration of the build you actually deploy, too.
A batch saves round trips, not you from partial failures. Some subrequests can succeed while another fails or gets throttled. I would rather see those individual outcomes than a reassuring green "batch complete" message with the awkward details left out.
Architecture and feedback
The UI submits through the job API and watches status and progress. The worker selects an executor, calls the shared Graph/report services, and updates the counts and state. Its callbacks reach the connected browser through SignalR. You can follow the operation without repeatedly refreshing the page.
There is support for certificate or client-secret authentication, CSV reports, name-pattern filtering, and Graph throttling retries/backoff. Before allowing writes, use an approved app registration with only the necessary permissions and test against a limited cohort. Keep credentials in User Secrets or Key Vault, not in source-controlled settings.
Intune.TagManager is MIT-licensed. Its repository includes the web, worker, and core projects, API endpoints, and setup guidance; source references in this draft use the pinned revision 8f26628. The queue makes bulk work easier to follow—not immortal. For that, you would need durable storage, not optimism and a browser tab.