Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Onboarding twenty new hires is a task. Onboarding two thousand is an operation. Here’s how the CSV bulk-create pipeline, and its scriptable Microsoft Graph alternative, turn a spreadsheet into a tenant full of working identities.
| Name [displayName] | User name [userPrincipalName] | Initial password | Block sign in | Job title | Department | Usage location |
|---|---|---|---|---|---|---|
| Alain Charon | alain@vmorecloud.onmicrosoft.com | ••••••••! | No | Systems Engineer | Infrastructure | US |
| Isabella Simonsen | isabella@vmorecloud.onmicrosoft.com | ••••••••! | No | Cloud Architect | Platform | US |
| Joseph Price | joseph@vmorecloud.onmicrosoft.com | ••••••••! | No | Service Desk | IT Ops | GB |
Every tenant eventually meets its first mass-onboarding moment — a merger, a new site opening, a term of student accounts, a contractor wave. The New user wizard in Microsoft Entra ID was built for one person at a time. Bulk create was built for the other case: dozens, hundreds, or thousands of identities provisioned from a single file.
This piece walks through what bulk creation actually does under the hood, the two practical ways to run it — the built-in CSV pipeline and Microsoft Graph PowerShell — where each one breaks, and a full step-by-step tutorial to run your own bulk import safely, on the first attempt.
Manually creating accounts scales linearly with tedium: each user is a form, a password, a set of attributes, a license assignment, a group membership. At any real headcount, that process becomes the bottleneck for onboarding day one — badges are printed, desks are assigned, but sign-in still isn’t ready.
Bulk creation collapses that into a single reviewable artifact: a spreadsheet. It’s auditable before submission, repeatable across environments, and — critically — it’s the same shape of file whether five people are onboarding or five hundred.
Bulk create is for internal member accounts. If you’re bringing in external partners or vendors, you want Bulk invite for B2B guest users instead — it sends invitation emails and follows a different consent flow entirely.
Both paths land in the same place — new objects in the directory — but they suit different operators and different scales.
Download a template, fill rows, upload through the Entra admin center. No scripting required. Best for HR-adjacent admins and one-off batches.
Import a CSV and loop New-MgUser per row. Full control over attributes, error handling, and license assignment in the same run.
Bundle multiple POST /users calls into a single JSON batch payload. The right tool when provisioning is triggered from another system entirely.
For most IT teams, the decision comes down to volume and repeatability. A one-time batch of forty seasonal staff is a portal job. A recurring quarterly intake tied to an HR export belongs in a script that can be scheduled, logged, and re-run.
The template downloaded from the portal isn’t an ordinary spreadsheet — its structure is load-bearing. Row one carries a version tag such as version:v1.0, and the column header row encodes both the human-readable label and the underlying property name, like Name [displayName] Required. Neither row should be touched.
| Column | Property | Required | Notes |
|---|---|---|---|
| Name | displayName | Required | Full display name shown across Entra and Microsoft 365 |
| User name | userPrincipalName | Required | Sign-in identity; no leading/trailing whitespace |
| Initial password | passwordProfile | Required | Must satisfy the tenant’s active password policy |
| Block sign in | accountEnabled | Required | Yes/No — counter-intuitively inverted from “enabled” |
| First / Last name | givenName / surname | Optional | Feeds the global address list |
| Job title / Department | jobTitle / department | Optional | Useful for dynamic group rules later |
| Usage location | usageLocation | Optional | Two-letter country code — required before license assignment will succeed |
Only the first four columns are mandatory. Everything else can stay blank in the template and be enriched later — through a second bulk update, a HR sync, or manually.
The single most common upload error is “Unknown CSV header found” — almost always caused by adding, renaming, or reordering a column. Extra columns are silently ignored, but a modified header row invalidates the whole file. Re-download a fresh template rather than editing an old one.
A bulk import is only as trustworthy as the row you didn’t check.
The portal CSV flow is deliberately narrow — it creates accounts and nothing more. The moment a batch needs conditional logic (different usage locations per office, license group assignment in the same run, custom attribute mapping from an HR export), Microsoft Graph PowerShell earns its complexity. The same source CSV can drive it — only the execution engine changes.
# Connect with the minimum scope this task needs Connect-MgGraph -Scopes "User.ReadWrite.All" # Source rows — same shape as the portal template $users = Import-Csv -Path "C:\Import\NewUsers.csv" foreach ($u in $users) { $passwordProfile = @{ Password = $u.InitialPassword ForceChangePasswordNextSignIn = $true } New-MgUser ` -DisplayName $u.DisplayName ` -UserPrincipalName $u.UserPrincipalName ` -MailNickname ($u.UserPrincipalName -split "@")[0] ` -AccountEnabled ` -PasswordProfile $passwordProfile ` -UsageLocation $u.UsageLocation ` -JobTitle $u.JobTitle ` -Department $u.Department Write-Host "Created:" $u.UserPrincipalName }
The trade is explicit: the portal path needs zero setup and produces a built-in results file; the scripted path needs Graph module installation and delegated permissions, but earns per-row error handling, inline license assignment, and something the portal doesn’t give you at all — a re-runnable, source-controlled onboarding pipeline.
Two tracks, same destination. Pick the Portal track for a one-off import with no tooling, or the PowerShell track if this needs to be repeatable.
Go to entra.microsoft.com with an account holding at least User Administrator. Global Reader and lower roles won’t see the Bulk create option.
Navigate to Identity → Users → All users, then select Bulk operations → Bulk create from the toolbar.
Select Download to get a fresh bulkCreateUserTemplate.csv. Don’t reuse an old saved copy — header formats change between versions.
Starting at row 4, add one user per line. At minimum, populate Name, User name, Initial password, and Block sign in. Leave the version row and header row exactly as downloaded.
Save the file with the .csv extension intact. Back on the Bulk create page, browse to the file and select it under Upload your CSV file.
Select Submit. Entra ID validates the file’s structure before processing anything — a clean file shows File uploaded successfully. Fix any flagged rows and resubmit if needed.
Watch the notification bell for job status, then open Bulk operation results to download a results file — it lists exactly which rows failed and why.
Check Users → All users in the portal, or confirm from PowerShell with Get-MgUser -Filter "UserType eq 'Member'". Remember: no invitation email was sent — you still need to deliver credentials yourself.
From an elevated PowerShell 7 session:
Request only what the task needs — broader scopes are a bigger blast radius if the script is ever compromised.
Use plain, predictable column names of your own choosing — this file isn’t the portal template, so its structure is entirely up to you. Save it locally, e.g. C:\Import\NewUsers.csv.
Use the script from the Editorial section above, or extend it to also call New-MgGroupMember or Set-MgUserLicense per row for a fully self-contained onboarding run.
Pipe results to a transcript or CSV export so failures are traceable, then confirm the batch with: