Karsten Palmvig's blog

Notes from the field on Unified Communications...

Office 365: Convert User Mailbox to Shared Mailbox

Office 365: Convert User Mailbox to Shared Mailbox

  • Comments 8
  • Likes

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
  • 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

  • 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?

  • 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.

  • 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.

  • 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

  • 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

  • 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 ???

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment