The Setup
I have a client that is moving their entire Exchange 2003 Organization to the cloud. This move requires an Exchange 2010 server to provide Hybrid connectivity as the Exchange 2003 server cannot directly migrate to Office 365. As such using Exchange 2010 provides us with a powerful tool for migrating mailboxes – PowerShell. What can this tool provide for us?
- Batch mailbox move to Exchange 2010
- Batch mailbox move to Office 365
- Batch licensing of all users moved
- Batch verification of mailbox
- Batch verification of licensing
Why would these be useful to the average admin? Even with relatively small moves of 25-100 users having a simple PowerShell to run versus running the Wizard in Exchange 2010 makes things easier. You can have a prepared one-liner to move mailboxes in batches. Also, an admin can create preselected groups saved in CSV files upon which to run the one-liners and run reports to see how far along the migrations are. This method gives us greater flexibility and better automation as well as being less tedious than examining each move individually to see what the process is doing.
The Problem
Let’s look at license validation. For my client we were moving users on a per site bases for ease of management and support. There were approximately 20 sites involved in their migration. Once a user is moved to the cloud there is a 30 day grace period for you to license users and as it turns out, this also led to a bit of complacency for some of the site migrations.
Gathering a User List
One advantage of the per site method (assuming Active Directory is organized the same way) is that we were able to match this site to an OU in active directory. In the first step we gathered up all the names of the users in a certain physical location (by OU):
get-user -OrganizationalUnit "localdomain.com/BranchOfficeName/Users" |ft userprincipalname
Copy the list of names from this list to a CSV file, in our case we called it upn.csv. Here is the format of the CSV file [upn.csv]:
upn hsimpson@localdomain.com bsmith@localdomain.com jschmoe@localdomain.com slobster@localdomain.com
Connect to Office 365 via PowerShell
Next we need to open up the Windows Azure AD Module for PowerShell (this window will be used to check licenses):
Run these commands in this window [1]:
$cred = Get-Credential Connect-MsolService -Credential $cred
Open a second Windows Azure AD Module for PowerShell window:
Run these commands in this window [2]:
$LiveCred = Get-Credential $Session = New-PSSession -name ExchangeOnline -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $LiveCred -Authentication Basic -AllowRedirection Import-PSSession $Session
List of Mailboxes in Office 365
Using the list of mailboxes from the OU query earlier, we need to now query what mailboxes are live in the cloud and ignore any errors (for mailboxes that are not in the cloud. Use the PowerShell window [2]:
Import-CSV "c:\scripts\upn.csv" | foreach {get-mailbox $_.smtp -erroraction silentlycontinue | ft userprincipalname}
Clean up results and save into a csv file [smtp.csv]:
smtp user1@domain.com user2@domain.com user3@domain.com
Validating licenses in the cloud
Now that we have a list of the mailboxes from a certain OU that are in the cloud, we need to validate if they have a license or not assigned to them in the cloud. In PowerShell window [1] run these commands:
$licenses = Import-CSV "c:\scripts\upn.csv" | foreach {get-MsolUser -UserPrincipalName $_.smtp} foreach ($lic in $licenses) {$lic.userprincipalname+" "+$lic.licenses}
This will give us a list of users who have not been licensed for Office 365.
Create CSV – Unlicensed Users
Once you have all the users and their license status in the cloud, we need to filter out the licensed users and keep only unlicensed users so we can fix their accounts. You can do this either in Excel or a notepad (sort by the license column in Excel). Once you have those in your file, save it to a ‘.csv’ with this format:
smtp user1@domain.com user2@domain.com user3@domain.com
Adding Licenses
Using PowerShell Window [1], enter these commands:
Import-CSV "c:\scripts\smtp.csv" | foreach {set-MsolUser -UserPrincipalName $_.SMTP -UsageLocation "US"} Import-CSV "c:\scripts\smtp.csv" | foreach {set-MsolUserLicense -UserPrincipalName $_.SMTP -AddLicense "[online domain]:[licensing option]"
The first line set the user location, which is required to assign a license and the second line will assign the user a license.
** Note, I used US for the location, please use your location for your script.
** Also, if you don’t know what your domain location or licensing option you need, just run this command in PowerShell window 1:
Get-MsolAccountSku | ft -auto
You should get a result like this:
You can now customize the second PowerShell command to match your AccountSkuId:
Import-CSV "c:\scripts\smtp.csv" | foreach {set-MsolUserLicense -UserPrincipalName $_.SMTP -AddLicense "ENTERPRISEAcc:ENTERPRISEPACK"
Once your licenses are added, your users will no longer receive a licensing error.
Hope this helps you with some of your Office 365 Licensing issues. Remember that these steps will work if you go full Office 365 or just want a hybrid Office 365 environment with only some of your mailboxes in the cloud.
Related Resources
Get-MsolAccountSku
MSOL Commands
Office 365 PowerShell Management