Automatically assign Office 365 licenses to new users

We recently setup the Azure Active Directory Sync Tool and noticed that it does not automatically assign licenses to new users. This can be a real pain for a big company so I decided to create a script that will automatically do this for us.

Step 1: Install required software

These steps are required once on your computer. However, you’ll likely need to install newer versions of the software periodically.

  1. Install the 64-bit version of the Microsoft Online Services Sign-in Assistant: Microsoft Online Services Sign-in Assistant for IT Professionals RTW.
  2. Install the 64-bit version of the Windows Azure Active Directory Module for Windows PowerShell: Windows Azure Active Directory Module for Windows PowerShell (64-bit version).

Step 2: Open the Windows Azure Active Directory Module

Find and open the Windows Azure Active Directory Module for Windows PowerShell. Normally the module is located in the start menu.

Step 3: Run the following command to create a new Event log. You may need to run this in an elevated Powershell console.

New-EventLog -LogName application -Source "Office 365 Log"

Now you can create a scheduled task that runs after the Azure Active Directory Sync Tool has synced and have it run the script below.

The following script will install the necessary modules, connect to Office 365 and assign licenses to any new users.
Keep in mind that you will want to update the $Username, $Password, $LicenseSKU, and $UsageLocation variables with your information

#Customizable information here
$username = "USERNAME HERE"
$password = "PASSWORD HERE"
$licensesku = "LICENSE SKU HERE"
#Before you can assign a license to a user, you must set the Usage Location for the user.  This is represented by the two-character ISO code for that region. EX: US
$usagelocation = "US"

try {
    #Attempts to connect to Office 365 and install Modules
    Import-Module MSOnline
    $pass = convertto-securestring -String "$password" -AsPlainText -Force 
    $credential = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $pass
    Connect-MsolService -Credential $credential -ErrorAction Stop
    $ExchangeSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://outlook.office365.com/powershell-liveid/" -Credential $credential -Authentication "Basic" -AllowRedirection
    Import-PSSession -AllowClobber $ExchangeSession >null
}
catch [Microsoft.Online.Administration.Automation.MicrosoftOnlineException] {
    #Logs error for incorrect password
    Write-Host "Please verify your username and password"
    Write-EventLog -LogName Application -Source "Office 365 Log" -EntryType Error -EventId 1 -Message "OFFICE 365 AUTOMATIC LICENSE ASSIGNMENT`n`nError Connecting to Office 365! Please verify your user name and password"
    exit
}

catch {
    #Log for any other error
    Write-Host "Error Connecting"
    Write-EventLog -LogName Application -Source "Office 365 Log" -EntryType Error -EventId 1 -Message "OFFICE 365 AUTOMATIC LICENSE ASSIGNMENT`n`nError Connecting to Office 365!"
    exit
}

#Get Users that are not disabled and need a license
$users = Get-MsolUser -All -UnlicensedUsersOnly | where {($_.WhenCreated -gt (get-date).AddDays(-1)) -and ($_.BlockCredential -eq $false)}
$totalcount = $users.Count
$displayname = $users | Select DisplayName | Format-Table -HideTableHeaders | Out-String 


if ($totalcount -gt 0) {
    #Assigns usage location
    $users | Set-MsolUser -UsageLocation $usagelocation
    #Assign license and write log
    $users | Set-MsolUserLicense -AddLicenses "$licensesku"
    Write-EventLog -LogName Application -Source "Office 365 Log" -EntryType Information -EventId 1 -Message "OFFICE 365 AUTOMATIC LICENSE ASSIGNMENT`n`nTotal License's assigned: $totalcount`nUser's Assigned: $displayname"
    exit
}
else {
    Write-Host "Zero licenses were assigned"
    exit
}

11 Comments

  1. Hi Jose,

    I noticed you are using the older MSOnline PowerShell module in your examples. It may be useful to start using the newer Azure Active Directory PowerShell V2 module instead, as we will begin deprecating the MSOnline module when we have migrated the functionality of the MSOnline module to the newer module – currently planned for the Spring of 2017.

    Thanks,

    Rob de Jong

  2. Jose, great script really came in handy. I just wanted to add that for our deplyment, we needed to add an extra switch to line 15. The AllowClobber. If not, then the script fails with:

    Import-PSSession : No command proxies have been created, because all of the requested remote commands would shadow existing local commands. Use the AllowClobber parameter if you want to shadow existing local commands.

    New Line 15: Import-PSSession -AllowClobber $ExchangeSession >null

  3. I work at a school. All Student usernames end with a 2 digit number. How could I edit line 32 to search for only those users?

    • Jose Espitia

      Strensnik, you should be able to do this by changing line 32 to:
      $users = Get-MsolUser -All -UnlicensedUsersOnly | where {($_.WhenCreated -gt (get-date).AddDays(-1)) -and ($_.BlockCredential -eq $false) -and ($_.UserPrincipalName -like”*[0-9]”)}

  4. Hi, is there a new script for PoweShell V2?

    • Jose Espitia

      Sorry Ben.. Unfortunately I don’t support Office 365 in my current role so I cannot create and test a new script.

Leave a Reply