Office 365: Convert User Mailbox to Shared Mailbox


Many administrators need to convert regular User Mailboxes to a Shared Mailbox after migration to Office 365. While the task is not very complex in itself, it is admittedly quite boring and you need to remember quota sizes and not least the syntax for removing the license.

I’ve put together a small script that will automate this task given two command line arguments in the format:

.\convertUserToShared.ps1 <user@domain.com> <sec-gr-shared-mailbox-name>

Note:

Remember to assign an email address to the security group or you won’t be able to use it in Exchange Online. You may also want to hide it from the address book (set attribute: msExchHideFromAddressBook to True).

Now, to be able to perform the necessary operations you need the following plug-ins:

And I really recoomend upgrading Powershell as well:

 

Connect to Exchange Online AND Office 365 with the following syntax prior to running the script:

   1: $LiveCred = Get-Credential
   2: $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://ps.outlook.com/powershell/" -Credential $LiveCred -Authentication Basic -AllowRedirection
   3: Import-PSSession $Session
   4: Connect-MsolService -Credential $LiveCred

 

I’ve commented directly in the source where needed, so the script should be fairly self explanatory:

   1: $count = $args.Count
   2: if ($count -lt 2) {
   3:     Write-Host
   4:     Write-Host "You need to specify username and security group as arguments: .\convertUserToShared.ps1 <username@domain.ext> <securitygroup>" -ForegroundColor Red
   5:     Write-Host
   6: }
   7: else {
   8:     $mbx = $args[0]
   9:     $secGroup = $args[1]
  10:     Write-Host Processing user: $mbx -ForegroundColor Yellow
  11:  
  12:     # Verify if group exist, remember to DirSync it first
  13:     $test = Get-Group $secGroup -ErrorAction SilentlyContinue
  14:     if ($test -ne $null) {
  15:  
  16:         # Verify if mailbox exist
  17:         $test = Get-Mailbox $mbx -ErrorAction SilentlyContinue
  18:         if ($test -ne $null) {
  19:     
  20:             # Do the "clever" stuff to find out if mbx is less than 4500 MB (leaves a little room up to 5 GB)
  21:             $stat = Get-MailboxStatistics $mbx
  22:             $tmp = $stat.TotalItemSize.Value.ToString().Split("(")[0].Replace(" ","")
  23:             $mb = Invoke-Expression $tmp/1MB
  24:             if ([int]$mb -lt 4500) {
  25:  
  26:                 # Setting the actual mailbox parameters
  27:                 Write-Host Converting user $mbx to shared and setting quota to 5 GB...
  28:                 Set-Mailbox -Identity $mbx -Type "Shared" -ProhibitSendReceiveQuota 5GB -ProhibitSendQuota 4.75GB -IssueWarningQuota 4.5GB
  29:  
  30:                 # Adding permissions
  31:                 Write-Host Adding permissions for $secGroup on $mbx
  32:                 Add-MailboxPermission $mbx -User $secGroup -AccessRights FullAccess
  33:                 Add-RecipientPermission $mbx -Trustee $secGroup -AccessRights SendAs -Confirm:$false
  34:  
  35:                 # Remove the license, Shared Mailboxes with a 5GB limit are free of charge
  36:                 Write-Host Removing license for $mbx
  37:                 $MSOLSKU = (Get-MSOLUser -UserPrincipalName $mbx).Licenses[0].AccountSkuId
  38:                 Set-MsolUserLicense -UserPrincipalName $mbx -RemoveLicenses $MSOLSKU
  39:                 Write-Host Done! -ForegroundColor Green
  40:  
  41:             }
  42:             else { Write-Host Mailbox is ([int]$mb) MB which is too large for conversion to a nonlicensed shared mailbox, reduce size and try again. -ForegroundColor Red }
  43:         }
  44:         else { Write-Host Mailbox: $mbx does not exist! -ForegroundColor Red    }
  45:     }
  46:     else { Write-Host Group: $secGroup does not exist! -ForegroundColor Red    }
  47: Write-Host
  48: }

 

Important:

If you’re synchronizing your accounts with Active Directory using DirSync (or FIM), please make sure that the following attributes are set on the modified Shared Mailbox objects in Active Directory:

msExchRemoteRecipientType = 100
msExchRecipientTypeDetails = 34359738368 (Optional but will set correct Remote Mailbox type on-prem)

If these attributes are not set correctly, you will risk that DirSync converts the cloud object back to a regular mailbox.

 

Note:

If you can make a regex that will do the job of line 22, you will be credited on this page! 🙂


Comments (17)

  1. Anonymous says:

    Thanks for your very useful script. It work like a charm. How do you setup value msExchHideFromAddressBook to the AD group? I didn’t find it under properties of this AD Group using ADSI Edit.

  2. Anonymous says:

    This is very useful, thanks.  I just tried this and it does exactly what you say, only it seems to retain some connection or attribute to the Active Directory user.  As in, if I try to edit anything in the shared mailbox it gives the normal "can't be performed on the object because the object is being synchronized from your on-premises organization" error.

    Have you run across this and is there anything else that needs to be done to "unlink" this from the AD sync user?

  3. Anonymous says:

    A couple of comments:
    It appears that Exchange Server 2010 SP3 RU8v2 or later will correctly set the msExchRemoteRecipientType so that migrated shared mailboxes are no longer incorrectly converted to regular after Directory Synchronization.

    As for converting a Federated User to Cloud Identity, that is not possible without converting the entire domain. If you want your Shared Mailboxes to be Cloud Identities, you should create them directly in Office 365 and not have a synchronized AD object for
    them.

  4. James Meredith says:

    You can replace lines 21 to 23 with a single line as follows:

    $mb = [float](([regex]::matches($((Get-mailboxStatistics $mbx.alias).TotalItemSize.Value.toString()),"d{1,3},{1}d*,*d*,*d*"))[0].value)/1048576

    With this code there is not need to cast $mb as an [int] in the if statement as the result is already in numeric form and therefore should test correctly with the -lt operator

  5. Paul Bradley says:

    I thought this was what I was looking for, but stumbled at an early hurdle.
    ‘Remember to assign an email address to the security group or you won’t be able to use it in Exchange Online’
    I cannot create a security Group using the address I wish to convert- there is already a user with that address.
    I need to convert a user to a mailbox without losing service or changing the address. Or am I missing something? I feel a bit out of my depth with this.

  6. Anonymous says:

    Pingback from Office 365 Exchange Online Strategy for Separated Employees

  7. Nicolai says:

    I found that sometimes the script will make the mailbox unreachable, if that happens add a license again to the user and wait for the mailbox to appear. Then add "Start-Sleep -s 10" to the script before the license is removed and run the script again.

    Also if wanting to give rights to a single user instead of a security group change this:
    $test = Get-Group $secGroup -ErrorAction SilentlyContinue
    To this:
    $test = Get-User $secGroup -ErrorAction SilentlyContinue

  8. Barclay Carl says:

    Convert User Mailbox to Shared Mailbox

    $mb = [float](([regex]::matches($((Get-mailboxStatistics $mbx.alias).TotalItemSize.Value.toString()),"d{1,3},{1}d*,*d*,*d*"))[0].value)/1048576

    http://www.migrategroupwisetooffice365.net

  9. Robert Lindahl says:

    Hi, I have issues with this since we use Dirsync.
    As soon as we move the user out of the OU sync filter scope (to a "recyclebin" OU, the office 365 shared mailbox gets deleted.. I’v solved it so far by manually, recovering the user -> assign license -> wait a whaile, and then remove the license.. Now the shared
    mailbox is back and the user account status is set to "In Cloud" instead of "Synced with Active Directory"
    So that is a workaround.. but do you think this could be done in a nice looking script ???

  10. Stefan Rairigh says:

    Robert,
    Have you ever found a solution to the DirSync issue? I have been converting user mailboxes from regular to shared when a user leaves the company. Up to now, by issuing the following PowerShell command:
    Set-mailbox user@domain.com –type shared
    However, I see it is now something available in the Exchange Admin web interface which is nice.
    In either case, I still have the issue of the converted shared mailbox still sync’ing with the local AD. Whenever I try to make a change to the shared mailbox in the cloud, I receive the following error:

    error
    The operation on mailbox “User, Joe” failed because it’s out of the current user’s write scope. The action ‘Set-Mailbox’, ‘EmailAddresses’, can’t be performed on the object ‘User, Joe’ because the object is being synchronized from your on-premises organization.
    This action should be performed on the object in your on-premises organization.

    I fear that deleting the AD object will in-turn remove the shared mailbox as others have mentioned.
    Does anyone know the proper method for making a shared mailbox cloud-only and detached from the local AD once it’s been converted from a regular mailbox to shared?

  11. disabpoint says:

    [tag:rollseyes], just give me a gui

  12. Tolle Colart says:

    I have a Server 2012 R2 AD with DirSync, but no on-premise Exchange. Only AD synced Office365 mailboxes.
    Problem is that I don’t have the msExchRemoteRecipientType or msExchRecipientTypeDetails attributes in AD.
    How can I add them? Or can I disable/remove the user that once had his own mailbox (and is now converted o shared mailbox) without losing the shared mailbox (as mentioned by Stefan Rairigh

  13. Rick_2CA says:

    Does manually changing the msExchRemoteRecipientType and msExchRecipientTypeDetails attributes miss anything that would be done by Exchange if we were to migrate back onprem to perform the conversion? The environment I’m in has been converting in the cloud
    for some time now. Recently a mailbox reverted back and we have hundreds of mismatched attributes.

    If you’re in a scenario with mismatched attributes is there any way to purposefully cause the account to revert from shared to user in order to test whether the attribute changes are working properly or not? We’ve so far been unable to recreate the issue.

    Thank you.

  14. When migrating back on-prem, Exchange (recent versions at least) should set the attributes correctly automatically. If you want to change the mailbox type to a regular user mailbox manually (which should also set attribs correctly), you would use Set-Mailbox
    -Type Regular for an on-prem mailbox or -RemoteRecipientType Migrated for an online mailbox.

  15. Inn VNix Ginner says:

    Good article! It comments some interesting points

  16. Rick_2CA says:

    Karsten – I want to convert a migrated mailbox to a shared mailbox in the cloud and then update the onprem attributes to the appropriate values to avoid Azure Active Directory Sync from converting it back to a user account. Set-RemoteMailbox -Type does
    not include "Shared" as an option.

    Officially we’re supposed to migrate the mailbox back onprem, convert to shared, and then migrate to the cloud again. Your blog post leads me to believe, based on the "Important" section above, that we could change the "Type" attributes via AD to avoid DirSync
    issues. That steps works in the sense that it makes the onprem attributes match the cloud attributes. Are you aware of any risks involved with performing that change? Does Set-Mailbox -Type do anything more than change the number in the attribute?

    Thank you.

  17. "Set-Mailbox -RemoteRecipientType SharedMailbox" is a valid syntax, you can refer to:
    https://technet.microsoft.com/en-us/library/bb123981(v=exchg.160).aspx for the full syntax. And please reach out to your TAM if you need more detailed information.