Wednesday, May 9, 2012

Common Office 365 PowerShell Scripts

I have compiled a list of useful PowerShell Scripts for use with Office 365.  I will continue to update the list over time.  I'll list the source for any scripts that aren't directly from Microsoft or that I've written from scratch.

I hope you find these useful!

* Update 5/10/13 - added scripts for changing user principal names (UPNs) singly or in bulk in Active Directory.*
* Update 5/6/13 - added scripts for changing mailboxes to shared singly or in bulk.*
* Update 5/1/13 - added script for changing from one SKU to another.*

First Time in Office 365 PowerShell per Machine
Set-ExecutionPolicy RemoteSigned
Close PowerShell Session
Remove-PSSession $session
Full Microsoft List of Office 365 Commandlets
Thomas Ashworth's PowerShell Resources on Technet
Import Contacts by CSV
$csv = Import-Csv “C:\Contacts.csv” foreach($line in $csv) {New-MailContact -Name $line.DisplayName -ExternalEmailAddress $line.EmailAddress -OrganizationalUnit “users” -Alias $line.Alias}
Connect to Office 365 PowerShell
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri -Credential $o365cred -Authentication Basic -AllowRedirection
Import-PSSession $session
Grant Access to One Mailbox
After you are connected, you must run the following command to give Alan full access to Bob’s mailbox:
Add-MailboxPermission -identity -user -AccessRights FullAccess -InheritanceType All
Grant Access to All Mailboxes
If you wanted to give Alan full access to all mailboxes in your environment you would run:
Get-Mailbox | Add-mailboxpermission -user -AccessRights FullAccess
Set Send-as Permissions for Users on Groups
This grants Alan SendAs permission for Bob's mailbox:

Add-RecipientPermission -AccessRights SendAs -Trustee


Set-Mailbox -Identity mailbox -GrantSendOnBehalfTo user
For Example:
Add-RecipientPermission "" -AccessRights SendAs -Trustee ""
(Credit How to Grant Full Access to an Office 365Mailbox)
Assign Licenses via CSV Import
That will output your sku's. Once you have that you would run a script like this:
Connect-MSOLService -Credential $adminCredential
$AccountSkuId = "sku:ENTERPRISEPACK"
$UsageLocation = "US"
$LicenseOptions = New-MsolLicenseOptions -AccountSkuId $AccountSkuId
$Users = Import-Csv c:\Users.csv
$Users | ForEach-Object {
Set-MsolUser -UserPrincipalName $_.UserPrincipalName -UsageLocation $UsageLocation
Set-MsolUserLicense -UserPrincipalName $_.UserPrincipalName -AddLicenses $AccountSkuId -LicenseOptions $LicenseOptions
If you wanted to do this for everyone you would change the line:
$users | Import-Csv c:\Users.csv
$users | get-msoluser -resultsize unlimited
(Credit Can I assign a license to a group of usersby PowerShell?)
Assign Licenses Granularly via PowerShell
Open Microsoft Online Services Module for Windows PowerShell and connect to the service:
Get-MsolAccountSku | Format-Table AccountSkuId, SkuPartNumber
The second column in this list is referenced in the next command as [SkuPartNumber] :
$ServicePlans = Get-MsolAccountSku | Where {$_.SkuPartNumber -eq "[SkuPartNumber]"}
This returns all the service plans
Secondly you need to assign the licence to the user(s):
Set-MsolUser -UserPrincipalName -UsageLocation GB
Set-MsolUserLicense -UserPrincipalName -AddLicenses [tenantname:AccountSkuId] -LicenseOptions $MyO365Sku
Repeat for any other licences you want to apply for other users or other licence options you want to apply to this user.
(Credit Granular license assignment from PowerShell)
Change Licenses from One SKU to Another via PowerShell
This script will identify all users with one SKU assigned and replace that SKU with a different one.  To test, change the "$Users = " variable assignment.

Be careful - removing licenses rather than replacing them correctly will de-provision user services and delete data.

  1. Connect to Microsoft Online Service PowerShell
  2. Set the variables for the SKU you want to replace and the one you want to add
  3. Change your UseageLocation and MaxResults if necessary
  4. Run the script
Connect-MSOLService -Credential $adminCredential
$AccountSkuRemove = "STANDARDPACK"
$UsageLocation = "US"
$LicenseOptions = New-MsolLicenseOptions -AccountSkuId $AccountSkuId
$Users = Get-MsolUser -MaxResults 50000 | Where-Object {$_.licenses[0].AccountSku.SkuPartNumber -eq $AccountSkuRemove -and $_.IsLicensed -eq $True}
$Users | ForEach-Object {Set-MsolUser -UserPrincipalName $_.UserPrincipalName -UsageLocation $UsageLocation Set-MsolUserLicense -UserPrincipalName $_.UserPrincipalName -RemoveLicenses $AccountSkuRemove -AddLicenses $AccountSkuId -LicenseOptions $LicenseOptions}
Convert Mailboxes to Shared Mailboxes - For Single Mailboxes
1. Start by checking your mailbox to see if it is under the 5 GB shared mailbox limit:
Get-MailboxStatisics | FL Total*
2. Change the mailbox type to shared:
Set-Mailbox -Identity -Type “Shared” -ProhibitSendReceiveQuota 5GB -ProhibitSendQuota 4.75GB -IssueWarningQuota 4.5GB
3. Add Full Access permissions to the mailbox - gives access to the contents of the mailbox:
Add-MailboxPermission -Identity -User -AccessRights FullAccess -InheritanceType All
4. Add Send As permissions to the mailbox - allows a user to send as if they were the mailbox itself:
Add-RecipientPermission -Identity -Trustee -AccessRights SendAs -Confirm:$false
5. Remove the user license from the mailbox
$MSOLSKU = (Get-MSOLUser -UserPrincipalName ).Licenses[0].AccountSkuId
 Set-MsolUserLicense -UserPrincipalName -RemoveLicenses $MSOLSKU

Convert Mailboxes to Shared Mailboxes in Bulk
1. Ensure that all mailboxes are under the 5 GB limit.
2. Create an input.csv file in c:\temp with the following format:
3. Run the following script in PowerShell:
Import-csv C:\temp\input.csv | foreach {
 $UPN = $_.userPrincipalName
 Set-Mailbox $UPN -Type “Shared” -ProhibitSendReceiveQuota 5GB -ProhibitSendQuota 4.75GB -IssueWarningQuota 4.5GB
 $MSOLSKU = (Get-MSOLUser -UserPrincipalName $UPN).Licenses[0].AccountSkuId
 Set-MsolUserLicense -UserPrincipalName $UPN -RemoveLicenses $MSOLSKU
(Credit Office 365 – Converting mailboxes to shared mailboxes)
Both of these scripts Alter the UPN Suffix for users.  They will both require you to open PowerShell and run the following command first:
import-module activedirectory
Change the UPN Suffix for a Single User, Search by SAM Account Name
Get-ADUser -Filter {SamAccountName -eq ""} | ForEach-Object ($_.SamAccountName) {$CompleteUPN = $_.SamAccountName + "@"; Set-ADUser -Identity $_.DistinguishedName -UserPrincipalName $CompleteUPN}
How to use it: replace with the user's SAM account name from Active Directory Users and Computers on the Account page and replace with the desired UPN suffix in the format of
Change the UPN Suffix for All Users in an OU
Get-ADUser -SearchBase "ou=,dc=,dc=" -SearchScope OneLevel -filter * | ForEach-Object ($_.SamAccountName) {$CompleteUPN = $_.SamAccountName + "@"; Set-ADUser -Identity $_.DistinguishedName -UserPrincipalName $CompleteUPN}
How to use it: replace and with the OU path that contains the user accounts you wish to modify and replace with the desired UPN suffix in the format of

Test Before You Run Your Scripts!
If you wish to test your scripts before running them (you should!) you can replace the final "$CompleteUPN}" with "$CompleteUPN -whatif}" and then run the script.  If the script doesn't work you will get no return output.  If it does, you'll be presented with something like this for all affected users:
What if: Performing operation "Set" on Target "CN=,OU=,DC=,DC=".

You can also test that you are affecting the correct user accounts by changing the end of the script.  Replace everything from the pipe | to the end with the following:

| FT -property name,userprincipalname

You'll be presented a table with the affected users' full names and UPNs.

Enhanced by Zemanta


  1. I have an improvement on your first script I use. It connects both the PowerShell command set at the same time. It assume all preliminary configuration is complete including installing the MSOnline module but on my machine I have it run as Connect-MsolAll

    Param($Cred = $null)

    $Mod = Get-Module ; if ($Mod.Name -Notcontains "MSOnline") {Import-Module MSOnline}
    $Cred = Get-Credential
    Connect-MsolService -Credential $Cred
    if (Get-PSSession -ComputerName * -ErrorAction SilentlyContinue) {exit}
    $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri `
    -Credential $Cred -Authentication Basic -AllowRedirection
    Import-PSSession $Session
    Write-Host "It is a best practice to exit from a session when you will nolonger be using it by entering the command remove-pssession $Session."

    1. Thats great! Thanks for sharing with us. I'll check it out and add it to my tool box.

  2. Very interesting stuff - do you know if you can also manage contracts, i mean as a partner could i create a contract? I see that you can get information about a contract, not sure if you can create one.

  3. Hi Scott, i just found your blog from Office365 Grid and you are doing a great work. Keep it up man. :D
    specially with posts like this

  4. I appreciate your comments, guys. I've been pleasantly surprised by the amount of traffic this particular post has generated. Apparently, PowerShell scripts are a point of interest for Office 365 admins. :)

  5. Hi....I'm trying to import contacts by csv but I get the following: The term '.New-MailContact' is not recognized as the name of a cmdlet...

    Can you explain why I might be having this problem? Thanks.

  6. is there a way to use the $cred from a secure file ??

    I'm using:
    $credential.Password | ConvertFrom-SecureString | Set-Content c:\Scripts\Admin.enc
    $SecurePassAdmin = c:\Scripts\Admin.enc
    $PasswordAdmin = Get-Content $SecurePassAdmin | ConvertTo-SecureString
    $AdminCredentials = New-Object System.Management.Automation.PsCredential ($AdminUser,$PasswordAdmin)

    then build the session with $admincredentials

    works from a shell session, but not when calling the script from another (vb ...) script,
    Ideas ?

  7. Hi Scott....Excellent article - I do have a quick question for the switching between different SKUs of the same family - I tried that in my environment and it keeps giving me error - Unable to bind UserPrincipalName - I do have multiple domains verified on the company's office 365 tenant - any clue why it's giving me that?!

  8. Hi, Just wanted to ask you to take a look at my own 365 Powershell script and maybe contribute any updates you feel would be valuable. Hopefully if will be usefull for youself as well.


Due to excessive spam, only registered users may post comments. Comments are unmoderated and post immediately but they are monitored. Inappropriate content will be removed promptly and will get you banned.

If you wish to communicate with me outside of this blog please e-mail me at

Related Posts Plugin for WordPress, Blogger...