Getty Images

Streamline Microsoft 365 onboarding with PowerShell

Learn how to simplify user provisioning in the cloud collaboration platform with faster results by seeing examples of scripts that work with Microsoft Graph.

Microsoft 365 onboarding is a common task for many admins, and one way to make it less of a chore is to automate the steps with PowerShell.

When a new employee starts, it's up to the admin to set up a new user account with all the permissions and resources they need. Depending on the organization, the process to onboard a user in Microsoft 365 can be complicated. However, most of the steps involve account provisioning, license assignment and any permission configuration for roles, applications or services. It's imperative, particularly in large organizations, to adopt a more streamlined approach to onboarding user accounts in Microsoft 365. The optimal way to do that is to learn how to use PowerShell and Microsoft Graph to build scripts that take care of most of the work.

Which PowerShell modules should you use?

Microsoft 365 provides standard PowerShell modules for the management of users.

Historically, you used either the Microsoft Online PowerShell module (MSOnline) or the Azure AD PowerShell module. Microsoft deprecated both PowerShell modules in March 2024 and will only provide support to fix critical security issues. This means the modules will still function until at least March 30, 2025.

Microsoft prefers that admins use newer tools, specifically the Microsoft Graph PowerShell SDK and Microsoft Graph PowerShell module. Microsoft has invested a lot of effort into Microsoft Graph to deliver a unified management approach that simplifies how admins work in Microsoft 365, while also offering better performance and scalability.

Microsoft recommends that IT workers migrate existing scripts and create new ones using the Microsoft Graph PowerShell module.

How to perform Microsoft 365 user provisioning tasks with PowerShell

Breaking down the user provisioning tasks, they are the following:

How to create a Microsoft 365 user account

The onboarding process usually kicks off when IT receives a help desk ticket asking for a new account within the on-premises AD or Microsoft Entra ID, formerly Azure AD. Many organizations synchronize accounts from on-premises AD.

PowerShell can create one or multiple user accounts on premises or directly within Microsoft Entra ID. If you add your users to an on-premises AD and then synchronize to Microsoft Entra ID, then you should use a different provisioning process in PowerShell. For cloud-only organizations, you can use Microsoft Graph PowerShell to create an account in Microsoft Entra ID, as shown in the following code:

$scopes = @(
    "User.ReadWrite.All"
    "Directory.ReadWrite.All"
)
Connect-MgGraph -Scopes $scopes
$password = @{ Password = '<Password>' }
New-MgUser `
    -DisplayName '<Display Name>' `
    -PasswordProfile $password `
    -AccountEnabled `
    -MailNickName '<Mail Nickname>' `
    -UserPrincipalName '<Username>@<Domain>.onmicrosoft.com'

If you needed to create multiple accounts, you could import a comma-separated values (CSV) file and repeat the same steps for each entry:

$users = Import-Csv -Path "C:\User.csv"
$tempPassword = @ { Password = '<Password>' }

foreach ($user in $users)
{
    New-MgUser `
    -DisplayName $user.DisplayName `
    -PasswordProfile $tempPassword `
    -AccountEnabled `
    -MailNickName $user.MailNickName `
    -UserPrincipalName '$($user.Username)@<Domain>.onmicrosoft.com'
}

How to assign licenses with PowerShell

After creating accounts, you need to assign licenses. As a side note, you should use group-based license assignments as much as possible. With the PowerShell method, you need to assign the license directly to the account so that it has access to the required services:

# Connect with the required permissions
$scopes = @(
    "Group.ReadWrite.All"
    "GroupMember.ReadWrite.All"
)
Connect-MgGraph -Scopes $scopes

$user = Get-MgUser `
    -ConsistencyLevel eventual `
    -Search '"UserPrincipalName:<Username>"'

$license = Get-MgSubscribedSku -All | `
    Where SkuPartNumber -eq 'EMSPREMIUM'

Set-MgUserLicense -UserId $user.Id `
    -AddLicenses @{SkuId = $license.SkuId} `
    -RemoveLicenses @()

If you use group license management but not dynamic groups, then you must assign the user to the specific security group that then applies the corresponding license(s):

$user = Get-MgUser `
    -ConsistencyLevel eventual `
    -Search '"UserPrincipalName:<Username>"'

$group = Get-MgGroup `
    -ConsistencyLevel eventual `
    -Filter "startsWith(DisplayName, 'E5 License Group')"

New-MgGroupMember `
    -GroupId $group.Id `
    -DirectoryObjectId $user.Id

Configuration of authentication methods

It is critical to secure provisioned accounts with extra authentication protections, such as single sign-on and multifactor authentication (MFA).

To assign MFA to a user, you can either set it at the account level or use conditional access policies for specific users and security groups. The latter is the easiest way to make sure MFA applies to an account.

The following PowerShell script prompts the user to register for MFA -- if the user dismisses the request, the system reminds them every two days until they register:

# Connect with the required permissions
$scopes = @(
    "Group.ReadWrite.All"
    "GroupMember.ReadWrite.All"
    "Policy.ReadWrite.AuthenticationMethod"
)
Connect-MgGraph -Scopes $scopes

$user = Get-MgUser `
    -ConsistencyLevel eventual `
    -Search '"UserPrincipalName:<Username>"'

# Enabling Multi-factor Authentication (MFA) Registration
$params = @{
    "@odata.context" = "https://graph.microsoft.com/v1.0/$metadata#authenticationMethodsPolicy"
    RegistrationEnforcement = @{
    AuthenticationMethodsRegistrationCampaign = @{
        SnoozeDurationInDays = 2
        State = "enabled"
        ExcludeTargets = @()
        IncludeTargets = @(
        @{
            Id = $user.Id
            TargetType = "user"
            TargetedAuthenticationMethod = "microsoftAuthenticator"
        })
    }
    }
}

Update-MgPolicyAuthenticationMethodPolicy `
    -BodyParameter $params

How to assign user permissions with PowerShell

After provisioning the account and adding protections and licenses, the next step is to add specific permissions, such as tenant roles, security or Microsoft 365 Groups, to the account.

Only assign tenant roles to the users who require them. Use security and Microsoft 365 Groups extensively to manage permissions and access to locations, such as SharePoint Online and Microsoft Teams:

$scopes = @(
    "User.ReadWrite.All"
    "Directory.ReadWrite.All"
    "Sites.Manage.All"
    "RoleManagement.ReadWrite.Directory"
)

# Assigning a Tenant Role to a User
$user = Get-MgUser `
    -ConsistencyLevel eventual `
    -Search '"UserPrincipalName:<Username>"'

$role = Get-MgRoleManagementDirectoryRoleDefinition `
    -UnifiedRoleDefinitionId 62e90394-69f5-4237-9190-012177145e10

$params = @{
    "@odata.type" = "#microsoft.graph.unifiedRoleAssignment"
    RoleDefinitionId = $role.Id
    PrincipalId = $user.Id
    DirectoryScopeId = "/"
}
New-MgRoleManagementDirectoryRoleAssignment `
    -BodyParameter $params

# Assigning an Owner to a Team
$user = "<Username>@<Domain>.onmicrosoft.com"
$owner = Get-MgUser -UserId $user
$properties = @{
    "@odata.type" = "#microsoft.graph.aadUserConversationMember";
    "[email protected]" = "https://graph.microsoft.com/v1.0/users/" + $owner.Id
}
$role = "owner"

$team = Get-MgTeam -TeamId "354d151c-cf85-4202-ba86-1ea47a271968"
New-MgTeamMember `
    -TeamId $team.Id `
    -Roles $role `
    -AdditionalProperties $properties

How to handle everyday user provisioning tasks using PowerShell

PowerShell automation is also excellent for Microsoft 365 provisioning beyond the standard onboarding jobs. A few of the most common are the following:

  • Configure Microsoft Teams settings, and create teams and channels.
  • Set up SharePoint sites and OneDrive for Business for file storage and collaboration.
  • Configure mailboxes, email aliases and mailbox permissions.
  • Implement email retention policies and archiving.
  • Set up email security features, such as antispam and antiphishing policies.
  • Configure data loss prevention policies.
  • Generate reports.
  • Review the audit logs.

As a relatively new offering, Microsoft Graph PowerShell might have some gaps in its range of functions. In such cases, consider using other established PowerShell modules or the admin portal UI:

# Update Microsoft Teams settings
$team = Get-MgTeam -TeamId "354d151c-cf85-4202-ba86-1ea47a271968"
$funSettings = @{ `
    "allowGiphy" = "true"; `
    "giphyContentRating" = "moderate"; `
    "allowStickersAndMemes" = "true"; `
    "allowCustomMemes" = "true"; `
}
Update-MgTeam `
    -TeamId $team.Id `
    -FunSettings $funSettings

# Review the Audit logs
$startDateTime = (Get-Date).AddDays(-7).ToString("yyyy-MM-ddTHH:mm:ssZ")
$endDateTime = (Get-Date).ToString("yyyy-MM-ddTHH:mm:ssZ")
Get-MgAuditLogDirectoryAudit `
    -Filter "activityDateTime ge $startDateTime and activityDateTime le $endDateTime"

Streamline the onboarding experience with PowerShell and Microsoft Graph

The Microsoft Graph and PowerShell modules provide excellent ways of provisioning items into the Microsoft 365 tenant. The main advantage for admins is to make repeatable and configurable scripts for a smoother and quicker user onboarding process. To learn more about working with Microsoft Graph, see official documentation here.

Liam Cleary is founder and owner of SharePlicity, a technology consulting company that helps organizations with internal and external collaboration, document and records management, business process automation, automation tool deployment, and security controls and protection. Cleary's areas of expertise include security on the Microsoft 365 and Azure platforms, PowerShell automation and IT administration. Cleary is a Microsoft MVP and a Microsoft Certified Trainer.

Dig Deeper on Microsoft messaging and collaboration