Automation is Useful

The easiest way to create a new Microsoft 365 account is through the Microsoft 365 admin center. Microsoft has done a lot of work over the last few years to smoothen the GUI and smoothen the process. But it’s good to have an alternative, especially when the need exists to accept inputs from sources like HR systems and create accounts for new employees. In most cases, organizations will use PowerShell for this kind of automation.

Other automation techniques work too, like the combination of SharePoint Online, Flow, and Power Apps described in Daler Sayfiddinov’s article. That’s a tad complicated for me, so let’s see what we can do with simple PowerShell.

Until now, most administrators who want to automate the creation of Azure AD accounts have used the Azure AD module. Microsoft plans to deprecate the Azure AD module, possibly at the end of 2022. Azure AD cmdlets will continue working afterwards without the benefit of support, so they can continue to be used with that caveat.

These articles give more insight into the Microsoft Graph PowerShell SDK and the transition from the Azure AD module:

Connecting to the Microsoft Graph for PowerShell SDK

Using the Microsoft Graph for PowerShell SDK to report Azure AD sign-ins.

Using Certificate-based Authentication with the Microsoft Graph PowerShell SDK.

Microsoft Forces Move from Azure AD Cmdlets for License Management.

Using the Microsoft Graph SDK for PowerShell with Azure Automation.

Creating a New Azure AD Account with New-AzureADUser

All Microsoft 365 accounts start as Azure AD accounts. As we’ll discuss later, assigning Microsoft 365 licenses transforms the Azure AD accounts into objects that can sign-into and work with Microsoft 365 apps. Two methods exist to create a new Azure AD account with PowerShell. The first is the New-AzureADUser cmdlet from the Azure AD module. The second is the New-MgUser cmdlet from the Microsoft Graph PowerShell SDK.

Accounts need an initial password, so let’s create one to use for our new account. Azure AD uses password profiles to hold password settings. In this example, we populate the settings with a password and a switch to force the user to change the password after they first sign-in.

$NewPassword = New-Object -TypeName Microsoft.Open.AzureAD.Model.PasswordProfile
$NewPassword.Password = "!NewPassword2022!"
$NewPassword.ForceChangePasswordNextLogin = $True

Apart from its password, the other properties needed to create a basic Azure AD account are:

  • UserPrincipalName: the value used to sign-into Microsoft 365. In most organizations, if the account is email-enabled, this value is also used for the primary SMTP address.
  • DisplayName: The human-facing name which appears in various GUIs.
  • MailNickName: Also known as the mailbox alias. This will be used if the account becomes mail-enabled.
  • AccountEnabled: Set to True to activate the account.

These properties combine to create a bare-bones Azure AD account. The account will work, but you should provide values for other properties to make the account more useful when people view details of the account’s owner. In many cases, these properties come from the HR department. Others are set by IT, such as the usage location. This is a two-character ISO-3166 country code to show where the account consumes services, and it’s important to set the value correctly so that license assignment works properly. Here’s an example of a more comprehensively populated command to create a new account::

New-AzureADUser -UserPrincipalName "Sue.Ricketts@Office365ITPros.com" -DisplayName "Sue Ricketts (Operations)" -PasswordProfile $NewPassword -AccountEnabled $True -MailNickName Sue.Ricketts -City NYC -CompanyName "Practical 365" -Country "United States" -Department "Operations" -JobTitle "GM Operations" -TelephoneNumber "+1 676 830 1101" -Mobile "+1 617 4466615" -State "New York" -StreetAddress "1, Avenue of the Americas" -Surname "Ricketts" -GivenName "Sue" -UsageLocation "US" -PhysicalDeliveryOfficeName "NYC"

If the account creation is successful, Azure AD returns the unique object identifier for the account and confirms the display name and user principal name. The unique or object identifier for an account is important when working with PowerShell because it’s used to tell Azure AD which object you want to manage.

ObjectId                             DisplayName               UserPrincipalName                UserType
--------                             -----------               -----------------                --------
3a6116ab-0116-490e-bd60-7e0cd9f36c9d Sue Ricketts (Operations) Sue.Ricketts@Office365ITPros.com Member

Create a New Azure AD Account with New-MgUser

Unlike the Azure AD module, which inherits the permissions of the signed-in account, a connection to the Microsoft Graph PowerShell SDK sets a scope for the permissions needed during a session. In this case, because the New-MgUser cmdlet performs directory updates, we connect with a scope of Directory.ReadWrite.All.

Connect-MgGraph -Scope Directory.ReadWrite.All

As noted in this article, the service principal used by the Microsoft Graph PowerShell SDK accumulates permissions over time, so it’s possible that the service principal already holds the permission. If not, you’ll be asked for administrator consent.

Creating a new Azure AD account using the New-MgUser cmdlet from the Microsoft Graph PowerShell SDK requires a hash table to store the password settings:

$NewPassword = @{}
$NewPassword["Password"]= "!NewPassword2022!"
$NewPassword["ForceChangePasswordNextSignIn"] = $True

Some property names used by New-MgUser differ in from those used by New-AzureADUser. This code creates the same user account as in the New-AzureADUser example:

New-MgUser -UserPrincipalName "Sue.Ricketts@Office365ITPros.com" -DisplayName "Sue Ricketts (Operations)" -PasswordProfile $NewPassword -AccountEnabled -MailNickName Sue.Ricketts -City NYC -CompanyName "Practical 365" -Country "United States" -Department "Operations" -JobTitle "GM Operations" -BusinessPhones "+1 676 830 1101" -MobilePhone "+1 617 4466615" -State "New York" -StreetAddress "1, Avenue of the Americas" -Surname "Ricketts" -GivenName "Sue" -UsageLocation "US" -OfficeLocation "NYC"

Figure 1 shows details of the new Azure AD account as viewed through the Microsoft 365 admin center.

The new Azure AD account as viewed through the Microsoft 365 admin center
Figure 1: The new Azure AD account as viewed through the Microsoft 365 admin center

To round out the new account, you should add a photo so that it shows up in the user profile card in applications like Teams. My view is that all Microsoft 365 accounts should have photos.

Assign Licenses with Azure AD

Our Azure AD account is functional in that the user can sign in. However, they need a license to do anything with Microsoft 365. The first step is to discover what licenses are assignable. Or rather, what product SKUs are available. The Get-AzureADSubscribedSKU cmdlet reveals the list of products installed in a tenant:

Get-AzureADSubscribedSKU | Format-Table SkuPartNumber, SkuId, ConsumedUnits

SkuId                                SkuPartNumber                        ConsumedUnits
-----                                -------------                        -------------
1f2f344a-700d-42c9-9427-5cea1d5d7ba6 STREAM                                           3
b05e124f-c7cc-45a0-a6aa-8cf78c946968 EMSPREMIUM                                       4
6fd2c87f-b296-42f0-b197-1e91e994b900 ENTERPRISEPACK                                 125
f30db892-07e9-47e9-837c-80727f46fd3d FLOW_FREE                                       10
a403ebcc-fae0-4ca2-8c8c-7a907fd6c235 POWER_BI_STANDARD                                6
26d45bd9-adf1-46cd-a9e1-51e9a5524128 ENTERPRISEPREMIUM_NOPSTNCONF                     5
710779e8-3d4a-4c88-adb9-386c958d1fdf TEAMS_EXPLORATORY                                2
90d8b3f8-712e-4f7b-aa1e-62e7ae6cbe96 SMB_APPS                                         2
8c4ce438-32a7-4ac5-91a6-e22ae08d9c8b RIGHTSMANAGEMENT_ADHOC                           6

A list of the full set of Microsoft 365 SKUs and identifiers is available online. The list allows you resolve internal Microsoft SKU names to the market name. For example, EnterprisePack means Office 365 E3. To assign a license, we create a license object using the identifier for the license we want to use and a license assignment object saying that we want to add the chosen license. Finally, the Set-AzureADUserLicense cmdlet applies the license to the account using its object identifier.

$NewLicense = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicense
$NewLicense.SkuId = “f30db892-07e9-47e9-837c-80727f46fd3d”
$LicenseAssignment = New-Object -TypeName Microsoft.Open.AzureAD.Model.AssignedLicenses
$LicenseAssignment.AddLicenses = $NewLicense
Set-AzureADUserLicense -ObjectId "3a6116ab-0116-490e-bd60-7e0cd9f36c9d" -AssignedLicenses $LicenseAssignment

Assign Licenses with the Microsoft Graph PowerShell SDK

Get-MgSubscribedSku is the cmdlet to return a list of products with the Microsoft Graph PowerShell SDK. The same information is available:

Get-MgSubscribedSku | Format-Table SkuPartNumber, SkuId, ConsumedUnits

SkuId                                SkuPartNumber                        ConsumedUnits
-----                                -------------                        -------------
1f2f344a-700d-42c9-9427-5cea1d5d7ba6 STREAM                                           3
b05e124f-c7cc-45a0-a6aa-8cf78c946968 EMSPREMIUM                                       4
6fd2c87f-b296-42f0-b197-1e91e994b900 ENTERPRISEPACK                                 125
f30db892-07e9-47e9-837c-80727f46fd3d FLOW_FREE                                       10
a403ebcc-fae0-4ca2-8c8c-7a907fd6c235 POWER_BI_STANDARD                                6
26d45bd9-adf1-46cd-a9e1-51e9a5524128 ENTERPRISEPREMIUM_NOPSTNCONF                     5
710779e8-3d4a-4c88-adb9-386c958d1fdf TEAMS_EXPLORATORY                                1
90d8b3f8-712e-4f7b-aa1e-62e7ae6cbe96 SMB_APPS                                         2
8c4ce438-32a7-4ac5-91a6-e22ae08d9c8b RIGHTSMANAGEMENT_ADHOC                           6

Assigning a license is simpler with the Microsoft Graph PowerShell SDK because we can pass the SKU identifier without setting it up first.

Set-MgUserLicense -UserId "Sue.Ricketts@Office365itpros.com" -Addlicenses @{SkuId = '1f2f344a-700d-42c9-9427-5cea1d5d7ba6'} -RemoveLicenses @() 

After assigning the licenses to the account, you can check that the right licenses are in place by running the Get-MgUserLicenseDetail cmdlet:

Get-MgUserLicenseDetail -UserId Sue.Ricketts@office365itpros.com | Format-Table SkuId, SkuPartNumber

SkuId                                SkuPartNumber
-----                                -------------
1f2f344a-700d-42c9-9427-5cea1d5d7ba6 STREAM
710779e8-3d4a-4c88-adb9-386c958d1fdf TEAMS_EXPLORATORY
8c4ce438-32a7-4ac5-91a6-e22ae08d9c8b RIGHTSMANAGEMENT_ADHOC
f30db892-07e9-47e9-837c-80727f46fd3d FLOW_FREE

The Office 365 licensing report article gives more information about dealing with SKUs, product identifiers, and so on.

Signing in With the New Account

The true test of our newly created and licensed account is to sign in and do some work. Because the password profile used when creating the account set a requirement to change the password at the first sign-in, the user is forced to update their account (Figure 2).

The new Azure AD account signs in and has to change its password
Figure 2: The new Azure AD account signs in and has to change its password

Once signed-in, the new account can access any of the Microsoft 365 services for which they possess a license. In Figure 3, the new account is conversing in a Teams conversation. I guess everything works!

The new Azure AD account working in Teams
Figure 3: The new Azure AD account working in Teams

Creating new Azure AD accounts with PowerShell isn’t hard. Like many tasks, preparation is key. Know the details of the users for whom you’re going to create accounts and know the licenses available for assignment and things should go smoothly.

About the Author

Tony Redmond

Tony Redmond has written thousands of articles about Microsoft technology since 1996. He is the lead author for the Office 365 for IT Pros eBook, the only book covering Office 365 that is updated monthly to keep pace with change in the cloud. Apart from contributing to Practical365.com, Tony also writes at Office365itpros.com to support the development of the eBook. He has been a Microsoft MVP since 2004.

Comments

  1. Srdjan

    Hi Tony, I’m in the process of migrating new MSOL scripts. However, I find it a bit difficult, because I can’t seem to find switches in Microsoft Graph that we had in MSOL.

    Let me elaborate…

    First, I create the hash table using the example you specified.

    After a bit of testing and studying the examples you provided on this page, I created this cmdlet for creating new user:

    New-MgUser -DisplayName “New user” -GivenName “New” -Surname “User” -UserPrincipalName “New.User@domain.com” -UsageLocation RS -PasswordProfile $NewPassword -AccountEnabled -MailNickName New.User | Export-Csv -Path G:\Office365_Graph\MS-graph-test1.csv -Encoding Unicode -Append

    and after that I run this one to assign a license to the newly created user:

    Set-MgUserLicense -UserId “New.User@domain.com” -Addlicenses @{SkuId = ‘MY-SKU-NUMBER’} -RemoveLicenses @()

    This works as a charm, but I’d like to tweak it a bit more:

    1. I would like to be able to force M365 to auto-generate password for that user (just like the old New-MsolUser command did it), so that I end up with CSV report that has usernames and auto-generated passwords. I am afraid that having a lot of users with the same initial password could be risky.

    2. I would like to avoid running separate Set-MgUserLicense cmdlet and incorporate it into the New-MgUser cmdlet.

    Can you think of something regarding those two, maybe you have a few tricks on your mind? 🙂

    Best regards,
    Srdjan

    1. Avatar photo
      Tony Redmond

      I could sell you a copy of the Office 365 for IT Pros eBook, where all of this is discussed in chapter 23.

      But https://practical365.com/azure-ad-account-creation-standardization/ has an example of an auto-generated password for use with New-MgUser. There are other examples available on the net.

      As to assigning a license along with the account, there is an AssignedLicenses parameter for New-MgUser https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.users/new-mguser?view=graph-powershell-1.0 Have you tried using that?

  2. Martin

    Thanks for this helpful and great blog post !

Leave a Reply