locked
FIM Enable-RemoteMailbox for Hybrid Exchange RRS feed

  • Question

  • Hello,

    Firstly I know that what I am trying to accomplish is not an easy task, possibly? But I have a scenario where I need to use FIM to enable remote mailboxes for new users being provisioned. I already have AD, and Office 365 licensing setup and working. The environment has a single Exchange 2013 server on-premises for management purposes and all mailboxes live in Exchange Online. All existing objects are remote mailboxes today as they have been moved to Exchange Online or provisioned as a remote mailbox manually. 

    Would it be best to use the PowerShell MA developed by Søren Granfeldt to create a new remote mailbox after the AD user has been provisioned? If so does anyone have any tips on the process and the PowerShell code to accomplish this task? 

    I was thinking I could basically write the import script to include attributes where I can determine if a remote mailbox already exists or not. Then write the export script based on an attribute like RemoteMailboxEnabled (true of false) and define my set and workflows to run the Exchange Outbound rule. Then let DirSync/ AADConnect take care of the rest as the account will have the necessary items for a mailbox to be created in Exchange Online at this point.

    Any help is greatly appreciated. 

    Thank you so much. 

    TM

    Tuesday, February 2, 2016 11:10 PM

Answers

  • I'd use a PowerShell MA to accomplish this task.

    The Granfeldt one works great, I've used a similar one in a recent Project and the following scripts might work directly with the Granfeldt PS MA, if not it should give you an idea on how it can get done. I've stripped out some business specific logic from the scripts so you'll have to modify them to suit your needs.

    The MA requires three scripts, schema, import and export.

    Schema:

    $obj = New-Object -Type PSCustomObject
    @(
      @{ Name="objectClass"; Type="String"; Value="person" }
      @{ Name="Anchor-AccountName"; Type="String"; Value=""}
      @{ Name="PrimarySmtpAddress";	Type="String"; Value="" }
      @{ Name="DisplayName"; Type="String"; Value="" }
      @{ Name="HiddenFromAddressListsEnabled"; Type="Bool"; Value=0 }
      @{ Name="RemoteRoutingAddress"; Type="String"; Value="" }
      @{ Name="EmailAddressPolicyEnabled"; Type="Bool";Value=0 }
    ) | foreach { 
        $obj | Add-Member -Type NoteProperty -Name "$($_.Name |
      $($_.Type)" -Value $_.Value
    }
    $obj

    The import script will look something like this:

    param(
    	$Username,
    	$Password    
    )
    
    BEGIN{    
        #initialize variable
        $connectionuri = "http://HybridServerName/PowerShell/"
        #end initialize variable
            
        # Create Credentials
        $securepw = ConvertTo-SecureString $Password -asplaintext -force
        $cred = new-object -typename System.Management.Automation.PSCredential -argument $Username, $securepw
    
        #create session
        $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $connectionuri -Credential $cred -Authentication Kerberos
        Import-PSSession $Session   
    }
    
    PROCESS
    {
        $list = get-remotemailbox -ResultSize unlimited | 
        select-object samaccountname,displayname,primarysmtpaddress,hiddenfromaddressListsenabled,EmailAddressPolicyEnabled,RemoteRoutingAddress
    
        foreach($item in $list)
        {    
            $obj = @{}    
            $obj.AccountName = $item.samaccountname
            $obj.PrimarySmtpAddress = $item.primarysmtpaddress
            $obj.DisplayName = $item.displayname
            $obj.HiddenFromAddressListsEnabled =$item.hiddenfromaddressListsenabled
            $obj.EmailAddressPolicyEnabled = $item.EmailAddressPolicyEnabled        
            $obj.RemoteRoutingAddress = $item.RemoteRoutingAddress
            $obj.objectClass = "person"        
            $obj.changeType ="Add"
            $obj
        }
    }
    
    END
    {
        Remove-PSSession $Session
    }

    And at last the export script:

    param(
    	$Username,
    	$Password
    )
    
    BEGIN{
    	#initialize variable    
        $mailaddresssuffix = "domainname"
        $connectionuri = "http://HybridServer/PowerShell/"
    
        # Create Credentials
        $securepw = ConvertTo-SecureString $Password -asplaintext -force
        $cred = new-object -typename System.Management.Automation.PSCredential -argument $Username, $securepw
            
        ##Create Exchange Powershell Session
        $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $connectionuri -Credential $cred -Authentication Kerberos    
        $null = Import-PSSession $Session   
    }
    
    PROCESS
    {        
        $identifier = $_."[Identifier]"
        $Anchor = $_."[Anchor]"
        $ObjectModificationType = $_."[ObjectModificationType]"
        $ObjectType = $_."[ObjectType]"
        $DN = $_."[DN]"
        $AccountName = $DN
        $PrimarySmtpAddress = $_."[PrimarySmtpAddress]"  
        $DisplayName = $_."[DisplayName]"
        $HiddenFromAddressListsEnabled = $_."[HiddenFromAddressListsEnabled]"
        $domailuser = "$mailaddresssuffix\$DN"
        $EmailAddressPolicyEnabled = $_."[EmailAddressPolicyEnabled]"
        $RemoteRoutingAddress = $_."[RemoteRoutingAddress]"
    
        if($EmailAddressPolicyEnabled -eq "False")
        {
          $EmailAddressPolicyEnabled = $false
        }
        else
        {
          $EmailAddressPolicyEnabled = $true
        }
        
        if($HiddenFromAddressListsEnabled -eq "True")
        {
          $HiddenFromAddressListsEnabled = $true
        }
        else
        {
          $HiddenFromAddressListsEnabled = $false
        }
      
    
        try
        {
            
        if($ObjectType -eq "person")
        {
        if($ObjectModificationType -eq "Add")
           {
            $result = Enable-RemoteMailbox -Identity $AccountName -RemoteRoutingAddress $RemoteRoutingAddress
        }
        if($ObjectModificationType -eq "Update")
           {
            $result = Set-RemoteMailbox -Identity $AccountName -EmailAddressPolicyEnabled $EmailAddressPolicyEnabled -HiddenFromAddressListsEnabled $HiddenFromAddressListsEnabled -RemoteRoutingAddress $RemoteRoutingAddress
        }        
    	if($ObjectModificationType -eq "Replace")
           {
            $result = Set-RemoteMailbox -Identity $AccountName -EmailAddressPolicyEnabled $EmailAddressPolicyEnabled -HiddenFromAddressListsEnabled $HiddenFromAddressListsEnabled -RemoteRoutingAddress $RemoteRoutingAddress
        }			
    		        
        }    
        $result = @{}
    	$result.Add("Status","0")
    	$result.Add("Identifier",$identifier)
    	$result.Add("ErrorName","")
    	$result.Add("ErrorDetail","")
        $result      
        }
        catch 
        {
          Remove-PSSession $Session
          $ErrorMessage = $_.Exception.Message
          $FailedItem = $_.Exception.ItemName
          $logError = "Error: " + $_.Exception.ToString()
          $result = @{}	
    	  $result.Add("Status","1")
    	  $result.Add("Identifier",$identifier)
    	  $result.Add("ErrorDetail", $logError)
    	  $result.Add("ErrorName","Error with user" + $AccountName  + ": " + $ErrorMessage)
    	  $result    
        }
    } 
    
    END
    {
      Remove-PSSession $Session
    }
    
    

    /Jesper


    --- Jesper Lönnqvist, Identity Architect http://addition-it.se

    • Marked as answer by TylorM Thursday, March 10, 2016 8:21 PM
    Saturday, February 6, 2016 11:06 AM

All replies

  • Hello,

    I'm not an that expert in Exchange Online, but aren't Mailbox automaticly provisioned if Azure AD user gets an approp. License ?

    So I don't see the need to Provision a Mailbox for users.

    Simple Provision User to AD, AADConnect then Provisions this user to AAD, then set O365 License (Exchange Online) to that user and mailbox will be provisioned.

    Or do I miss anything ?

    /Peter


    Peter Stapf - ExpertCircle GmbH - My blog: JustIDM.wordpress.com

    Wednesday, February 3, 2016 4:06 PM
  • I'd use a PowerShell MA to accomplish this task.

    The Granfeldt one works great, I've used a similar one in a recent Project and the following scripts might work directly with the Granfeldt PS MA, if not it should give you an idea on how it can get done. I've stripped out some business specific logic from the scripts so you'll have to modify them to suit your needs.

    The MA requires three scripts, schema, import and export.

    Schema:

    $obj = New-Object -Type PSCustomObject
    @(
      @{ Name="objectClass"; Type="String"; Value="person" }
      @{ Name="Anchor-AccountName"; Type="String"; Value=""}
      @{ Name="PrimarySmtpAddress";	Type="String"; Value="" }
      @{ Name="DisplayName"; Type="String"; Value="" }
      @{ Name="HiddenFromAddressListsEnabled"; Type="Bool"; Value=0 }
      @{ Name="RemoteRoutingAddress"; Type="String"; Value="" }
      @{ Name="EmailAddressPolicyEnabled"; Type="Bool";Value=0 }
    ) | foreach { 
        $obj | Add-Member -Type NoteProperty -Name "$($_.Name |
      $($_.Type)" -Value $_.Value
    }
    $obj

    The import script will look something like this:

    param(
    	$Username,
    	$Password    
    )
    
    BEGIN{    
        #initialize variable
        $connectionuri = "http://HybridServerName/PowerShell/"
        #end initialize variable
            
        # Create Credentials
        $securepw = ConvertTo-SecureString $Password -asplaintext -force
        $cred = new-object -typename System.Management.Automation.PSCredential -argument $Username, $securepw
    
        #create session
        $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $connectionuri -Credential $cred -Authentication Kerberos
        Import-PSSession $Session   
    }
    
    PROCESS
    {
        $list = get-remotemailbox -ResultSize unlimited | 
        select-object samaccountname,displayname,primarysmtpaddress,hiddenfromaddressListsenabled,EmailAddressPolicyEnabled,RemoteRoutingAddress
    
        foreach($item in $list)
        {    
            $obj = @{}    
            $obj.AccountName = $item.samaccountname
            $obj.PrimarySmtpAddress = $item.primarysmtpaddress
            $obj.DisplayName = $item.displayname
            $obj.HiddenFromAddressListsEnabled =$item.hiddenfromaddressListsenabled
            $obj.EmailAddressPolicyEnabled = $item.EmailAddressPolicyEnabled        
            $obj.RemoteRoutingAddress = $item.RemoteRoutingAddress
            $obj.objectClass = "person"        
            $obj.changeType ="Add"
            $obj
        }
    }
    
    END
    {
        Remove-PSSession $Session
    }

    And at last the export script:

    param(
    	$Username,
    	$Password
    )
    
    BEGIN{
    	#initialize variable    
        $mailaddresssuffix = "domainname"
        $connectionuri = "http://HybridServer/PowerShell/"
    
        # Create Credentials
        $securepw = ConvertTo-SecureString $Password -asplaintext -force
        $cred = new-object -typename System.Management.Automation.PSCredential -argument $Username, $securepw
            
        ##Create Exchange Powershell Session
        $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $connectionuri -Credential $cred -Authentication Kerberos    
        $null = Import-PSSession $Session   
    }
    
    PROCESS
    {        
        $identifier = $_."[Identifier]"
        $Anchor = $_."[Anchor]"
        $ObjectModificationType = $_."[ObjectModificationType]"
        $ObjectType = $_."[ObjectType]"
        $DN = $_."[DN]"
        $AccountName = $DN
        $PrimarySmtpAddress = $_."[PrimarySmtpAddress]"  
        $DisplayName = $_."[DisplayName]"
        $HiddenFromAddressListsEnabled = $_."[HiddenFromAddressListsEnabled]"
        $domailuser = "$mailaddresssuffix\$DN"
        $EmailAddressPolicyEnabled = $_."[EmailAddressPolicyEnabled]"
        $RemoteRoutingAddress = $_."[RemoteRoutingAddress]"
    
        if($EmailAddressPolicyEnabled -eq "False")
        {
          $EmailAddressPolicyEnabled = $false
        }
        else
        {
          $EmailAddressPolicyEnabled = $true
        }
        
        if($HiddenFromAddressListsEnabled -eq "True")
        {
          $HiddenFromAddressListsEnabled = $true
        }
        else
        {
          $HiddenFromAddressListsEnabled = $false
        }
      
    
        try
        {
            
        if($ObjectType -eq "person")
        {
        if($ObjectModificationType -eq "Add")
           {
            $result = Enable-RemoteMailbox -Identity $AccountName -RemoteRoutingAddress $RemoteRoutingAddress
        }
        if($ObjectModificationType -eq "Update")
           {
            $result = Set-RemoteMailbox -Identity $AccountName -EmailAddressPolicyEnabled $EmailAddressPolicyEnabled -HiddenFromAddressListsEnabled $HiddenFromAddressListsEnabled -RemoteRoutingAddress $RemoteRoutingAddress
        }        
    	if($ObjectModificationType -eq "Replace")
           {
            $result = Set-RemoteMailbox -Identity $AccountName -EmailAddressPolicyEnabled $EmailAddressPolicyEnabled -HiddenFromAddressListsEnabled $HiddenFromAddressListsEnabled -RemoteRoutingAddress $RemoteRoutingAddress
        }			
    		        
        }    
        $result = @{}
    	$result.Add("Status","0")
    	$result.Add("Identifier",$identifier)
    	$result.Add("ErrorName","")
    	$result.Add("ErrorDetail","")
        $result      
        }
        catch 
        {
          Remove-PSSession $Session
          $ErrorMessage = $_.Exception.Message
          $FailedItem = $_.Exception.ItemName
          $logError = "Error: " + $_.Exception.ToString()
          $result = @{}	
    	  $result.Add("Status","1")
    	  $result.Add("Identifier",$identifier)
    	  $result.Add("ErrorDetail", $logError)
    	  $result.Add("ErrorName","Error with user" + $AccountName  + ": " + $ErrorMessage)
    	  $result    
        }
    } 
    
    END
    {
      Remove-PSSession $Session
    }
    
    

    /Jesper


    --- Jesper Lönnqvist, Identity Architect http://addition-it.se

    • Marked as answer by TylorM Thursday, March 10, 2016 8:21 PM
    Saturday, February 6, 2016 11:06 AM
  • Thank you Jesper. That is exactly what I needed to get started. 
    Thursday, March 10, 2016 8:23 PM
  • Provision the object as a mail-user, but flow these values to make it a "remote mailbox"

    • The correct targetaddress (create a test user via EMC to see what the domain should be)
    • msExchRecipientDisplayType = -2147483642
    • msExchRecipientTypeDetails = 2147483648
    • msExchRemoteRecipientType = 1
    • msExchAddressBookFlags = 1

    Mike Crowley | MVP
    My Blog -- Baseline Technologies

    Thursday, May 26, 2016 1:59 AM
  • You would need to install MIMWAL to generate unique attributes in your directory for SMTP address and alias. https://github.com/Microsoft/MIMWAL/wiki

    Then all you need to make sure you do is populate the required EXO attributes for a remote mailbox such as:

    • msExchRecipientDisplayType = -2147483642
    • msExchRecipientTypeDetails = 2147483648
    • msExchRemoteRecipientType = 1
    • targetAddress = SMTP:first.last@tenant.onmicrosoft.com
    • mail = first.last@domain.com
    • proxyAddresses = SMTP:first.last@domain.com; smtp:first.last@tenant.onmicrosoft.com;
    • optional: msExchHideFromAddressBook = False (or True)

    Then you would need some sort of automated process to license the mailbox after your user syncs to the tenant.

    Wednesday, June 1, 2016 3:41 PM