Monthly Archives: December 2013

Office 365 PowerShell Toolbox – Oneliners to rule them all!

In this post, I will try to add some of the commands you need for managing Office 365, and some code snipets to do pre-migration checks and so on.

I will edit this post and keep adding things to keep them in one place.

Connecting to MSOL/Exchange Online

To connect to MSOL you simple run:

Connect-MsolService

To connect to Exchange Online:

$UserCredential = Get-Credential

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $UserCredential -Authentication Basic -Allow

Import-PSSession $Session

If you you are behind a proxy-server, you might need to add some session options. Like this (if you configured proxy in IE):

$proxysettings = New-PSSessionOption -ProxyAccessType IEConfig
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell -Credential $UserCredential -Authentication Basic -Allow -SessionOption $proxysettings

To save your credentials to be used in an automated script, you can do this:

# Get the credential into a variable
$MyCredential = Get-Credential

# Convert the password to an encrypted string and save to file
$MyCredential.Password | ConvertFrom-SecureString | Out-File .\Password.txt

# To load the credential...

# Set your username
$User = "[email protected]"

# Get the password from the file
$Password = Get-Content .\Password.txt | ConvertTo-SecureString

# Build the credential
$O365Credential = New-Object System.Management.Automation.PsCredential($User,$Password)

That credential can now be used togheter with the Connect-MsolService/New-PSSession cmdlets.

List all users and their AccountSkuId/License
This might sound easy, but the “Get-MsolUser”-cmdlet is returning an advanced object which makes it a bit difficult to export to for example a csv-file.

But if you use the Select-Object-cmdlet togheter with an expression you will get the job done!

You could to something like this to expand the AccountSkuId for all your users:

Get-MsolUser -All | Select-Object UserPrincipalName, @{Name="License" ; Expression={ ($_ | select -ExpandProperty Licenses | select -ExpandProperty AccountSkuId ) } }

Just pipe that to for example Export-Csv to save the information on disk.

Duplicates in forwarding address

If you have multiple smtp-domains, you might run into a problem with duplicates if you only have one *.onmicrosoft.com domain (simpler than creating multiple ones). Want to see if this is a problem in your domain?

This is one way of doing it:

$Duplicates=Get-ADUser -Filter * | Group-Object { ($_.UserPrincipalName -split "@")[0] } | Where-Object Count -gt 1

$Duplicates now contains all of the users that will be a problem if you only have one “forwarding domain”. There are many options to solve this, forward to something else (AccountName or similiar), add a part of the maildomain left of the @-sign etc…

Managing Mobile Devices

To add a device for a user:

Set-CASMailbox -Identity '[email protected]' -ActiveSyncAllowedDeviceIDs ($MyArrayWithDeviceIDs)

To get all device id’s associated with a user:

Get-CASMailbox -Identity '[email protected]' | select -ExpandProperty ActiveSyncAllowedDeviceIDs

Clear all allowed devices:

Set-CASMailbox -Identity '[email protected]' -ActiveSyncAllowedDeviceIDs $null

Setting a license

To give a user a license you could do something like this:

# Create the license options (if you need to disable some plans)
$LicenseOptions = New-MsolLicenseOptions -AccountSkuId $AccountSkuId -DisabledPlans $DisabledPlans

# Set the country (two letter "code")
Set-MsolUser -UserPrincipalName $UserAccount -UsageLocation $UsageLocation

# Set the license
Set-MsolUserLicense -UserPrincipalName $UserAccount -AddLicenses $AccountSkuId -LicenseOptions $LicenseOptions

# If you don't need to disable anything just use this instead of the above:
Set-MsolUserLicense -UserPrincipalName $UserAccount -AddLicenses $AccountSkuId

Creating Shared Mailboxes
To create a shared mailbox, you first have to give it a temporary license to create the mailbox (see above), then set it to shared, remove the license and add the permissions that are needed.

If the mailbox has a license you could do something like this:

# Set it to shared (mailbox need to exist first, so set a license, wait, and then try this)
Set-Mailbox '[email protected]' -Type Shared -ProhibitSendReceiveQuota 5GB -ProhibitSendQuota 4.75GB -IssueWarningQuota 4.5GB

# Set full access permissions
Add-MailboxPermission '[email protected]' -User 'GroupOrUserName' -AccessRights FullAccess -Confirm:$false

# Set 'SendAs' permission if needed
Add-RecipientPermission '[email protected]' -Trustee 'GroupOrUserName' -AccessRights SendAs -Confirm:$false

# Remove the license
Set-MsolUserLicense -UserPrincipalName '[email protected]' -RemoveLicenses $AccountSkuId

Change UPN of a licensed user
If the user UPN prefix (left of @) changes, DirSync will fix it automatically, if the domain part change, you need to run a few commands to change it.

The overall process is to change it in the On-Prem AD, change it in Azure to your “*.onmicrosoft.com”-domain, and then change it to the new domain.

Example, we need to change John Doe’s smtp domain from “contoso.com” to “contoso2.com”:


# Set the new UPN in Active Directory
Set-Aduser -identity JohnDoe -UserPrincipalName '[email protected]'

# Change the UPN in Azure to a temporary one
Set-MsolUserPrincipalName -UserPrincipalName '[email protected]' -NewUserPrincipalName '[email protected]'

# Change it to the new one
Set-MsolUserPrincipalName -UserPrincipalName '[email protected]' -NewUserPrincipalName '[email protected]'

Run a DirSync and you are done!

Add a Room
To add a room mailbox and set it to auto-accept a booking (if the time slot is free), and make it possible for your users to book it a year ahead (for example) you do the following:


# Create the room (with seats for 20 people)
New-Mailbox -Name "ConferenceRoom1" -DisplayName "Conference Room 1" -PrimarySmtpAddress "[email protected]" -Office "Contoso HQ" -ResourceCapacity 20 -Room

# Make it accept invitations if the time slot is free, 
Set-CalendarProcessing "ConferenceRoom1" -AutomateProcessing AutoAccept -BookingWindowInDays 365

If you run Outlook 2010 or newer (or the OWA) you most certainly want to create a roomlist. The users can then pick that list and see all available rooms right away. You might want to name it after the Office location or similar.

To add a room list and add a room to that list you do the following:


# Add the room list
New-DistributionGroup -Name "ContosoHQ-Rooms" -DisplayName "Contoso HQ" –PrimarySmtpAddress "[email protected]" –RoomList

# Add a room to it
Add-DistributionGroupMember –Identity "ContosoHQ-Rooms" -Member "ConferenceRoom1"

You might need to update your offline address book before this works properly in Outlook, it should work pretty much instantly in the OWA.

Migrating from Lotus Notes to Office 365 – The PowerShell Saga

The last few months have been pretty intense, but we finally finished moving ~18000 mailboxes from Lotus Notes to Office 365. I went to the first startup meeting for the implementation part of the project in late September, and we finished most of the migration this week, which was pretty satisfying to say the least 🙂

It has been a long journey (done in a short timeframe), and a lot of things needed to be done in order for it to work.

Some of the obstacles we (and probably everyone who does a migration) needed to solve were:

  • Changing UPN’s on all the accounts to the users primary smtp address
  • Establish ADFS and DirSync
  • Changing certificates that were using the current UPN’s and therefor would be rendered invalid.
  • Import the ~8000 accounts that only existed in Domino and not in Active Directory and keep them synced.
  • Sync the other 10000 accounts that existed in both Domino and Active Directory
  • Migrate distribution lists
  • Migrate rooms
  • Migrate shared mailboxes with their access lists
  • Build forms to enable users to do some of the management themselves
  • Make sure mail flow works during the “hybrid” period
  • Migrating mobile device id’s allowed to sync through Active Sync
  • Provisioning of new accounts in Office 365 that work with our current processes
  • Automate all the common tasks (creating mailboxes, shared mailboxes, managing distribution lists, approving devices, managing licenses etc.)
  • And more… 🙂

Since a lot of people out there are probably doing, or will be doing, the same thing we did, I will try to do a couple of post on how we solved these tasks (at least those related to powershell), share some code and good cmdlets for managing everything from rooms to mobile devices,

Hopefully this will become a good repository for myself and for anyone out there facing the same challenge we did 🙂