๐Ÿ‘ฅ Recipe ยท User & Group Management

Bulk Onboard Users from an Excel File Using a PowerShell and Microsoft Graph Script

Create Entra ID accounts, set profile properties, and assign group memberships in a single scripted pass driven by a simple Excel roster

Complexity

Intermediate

Impact

user-management + automation + entra-id + bulk-operations + onboarding

Context

Why This Matters

New-hire onboarding is one of the most repetitive โ€” and error-prone โ€” tasks in a Microsoft 365 tenant. Creating each user by hand in the admin center means manually entering names, setting temporary passwords, typing department and phone data, and then clicking through each group to add the new hire. When HR hands you a batch of five, ten, or fifty starters for the same day, the manual approach is slow, inconsistent, and easy to mess up.

This recipe provides a reusable PowerShell script that reads a plain Excel file (columns: Name, Phone, Groups, Department) and onboards every row into Entra ID via the Microsoft Graph PowerShell SDK. The spreadsheet becomes your source of truth: HR fills it in, you run the script, and the tenant is updated in minutes.

Run this recipe any time you need to bulk-provision accounts โ€” new-hire waves, intern cohorts, seasonal staff, M&A onboarding, or migrating users from another identity system where you can export a CSV/XLSX of names, phones, departments, and group memberships.

Expected Outcomes

After completing this recipe you will have:

  • A parameterized PowerShell script (Onboard-Users.ps1) that bulk-creates Entra ID users from an Excel roster.
  • Each new user provisioned with display name, first/last name, UPN, mail nickname, department, business phone, usage location, and a forced-change temporary password.
  • Each new user added to all groups listed in the Groups column (semicolon-separated), with group IDs cached for efficiency.
  • Idempotent behavior โ€” re-running the script skips existing users and existing group memberships rather than failing.
  • A -WhatIf dry-run mode so you can preview every create and every group-add before committing.
  • A console summary table showing per-user status (CREATED, EXISTED, FAILED) and per-group outcomes.

Risks & Considerations

Warnings and gotchas

  • Temporary password handling. The script takes the temp password as a mandatory parameter โ€” do not hard-code it into the script or check it into source control. Prefer a one-time password generator or Read-Host -AsSecureString in production.
  • UPN collisions. The script builds UPNs as firstname.lastname@domain. Two users with the same name will collide โ€” add a middle initial or employee ID column for large rosters.
  • No license assignment. This recipe creates accounts and sets usageLocation, but does not assign licenses. Use group-based licensing on the groups you add users to, or extend the script with Set-MgUserLicense.
  • Group name ambiguity. Groups are resolved by displayName. If two groups share the same name, the first match wins โ€” use object IDs or mailNickname for disambiguation in larger tenants.
  • Always dry-run first. Run with -WhatIf against the full spreadsheet before the real run. Eyeball the UPNs and group names in the output.
  • Compliance. Entra ID creation events are audited. Make sure your change-management process (ticket ID, HR approval) is attached to the run, and do not commit the Excel roster with PII to a public repo.
  • Rate limits. For rosters over ~100 users, expect Graph throttling. Add Start-Sleep between iterations or batch with -BatchId if needed.

Required Permissions

PermissionWhy It's Needed
User.ReadWrite.AllCreate new user accounts and set department, phone, and password profile.
Group.ReadWrite.AllResolve groups by display name and add new users as members.
Directory.Read.AllLook up existing users to detect duplicates before creating.

The fastest way to get this done โ€” just ask Dex. Copy the prompt below and paste it into your Dex conversation.

For IT Admins

Paste into Dex CoAdmin

Onboard the users in the attached Excel file ({file}) into our Microsoft 365 tenant. For each row, create the Entra ID account using domain {domain}, set a temporary password that must be changed at first sign-in, populate department and phone, and add the user to every group listed in the Groups column (semicolon-separated). Skip users that already exist. Give me a summary of who was created and any failures.
Try in Dex CoAdmin