Wednesday, July 15, 2015

Creating Shared Mailbox in a Hybrid Deployment

The first thing to be aware of when creating shared mailboxes in a hybrid deployment is security. Sharing mailboxes between on-premises and O365 is not supported. So, if a group of people need to share a mailbox then their mailboxes all need to be on-premises or all in O365.

On-Premises Shared Mailboxes

Creating an on-premises shared mailbox is pretty straight forward. Create the shared mailbox in the on-premises Exchange and it all works.

In Exchange 2013, shared mailboxes are explicitly listed as a recipient type in the Exchange admin center (EAC). You can create and manage the shared mailboxes there.

In Exchange 2010, shared mailboxes are not part of the Exchange Management Console (EMC). You need to create the shared mailbox by using the New-Mailbox cmdlet in the Exchange Management Shell (EMS). For example:
New-Mailbox HelpDesk -shared -UserPrincipalName HelpDesk@MyDomain.com
After creating the shared mailbox in Exchange 2010, you need to give users permission to access it. Assign Full Mailbox permissions to let users manage the contents of the mailbox. You may also want to give SendAs permissions depending on your scenario.

Office 365 Share Mailboxes

In Office 365, the web-based management interface provides the same option to create shared mailboxes as Exchange 2013 does. However, in a hybrid environment, you can't create the shared mailboxes directly in Office 365.

If you create the share mailbox directly in Office 365 there is no Active Directory reference to the shared mailbox on-premises. This prevents Outlook from properly adding the shared mailboxes because autodiscover does not work properly. In a hybrid environment, autodiscover is directed to the on-premises Exchange organization and won't be able to direct Outlook to the correct location of the shared mailbox because there is no information in Active Directory about the shared mailbox in the on-premises AD.


In a hybrid environment, you should perform the following steps instead:
  1. Create a Remote Mailbox in Office 365 from the on-premises Exchange organization.
  2. Run Dirsync (or wait for several hours).
  3. In Office 365, convert the mailbox to a shared mailbox. Available when the recipient is selected as seen in the screenshot to the right.
  4. In Office 365, configure Full Access and SendAs permissions to the shared mailbox as required.
It's a bit more of a hassle to create a shared mailbox in Office 365 for a hybrid environment, but it does work!

When you create the shared mailbox directly in Office 365, you'll see the following symptoms:
  • Shared mailboxes are not automatically added to Outlook.
  • If you attempt to add the shared mailbox to Outlook manually in the properties of the Exchange account, then Outlook will continually prompt for credentials and hang.

Tuesday, July 7, 2015

Script for Exchange 2013 Message Tracking

Exchange Server 2010 had a graphical utility for analyzing message tracking logs. Unfortunately, this tool was removed from Exchange Server 2013. Instead in Exchange Server 2013, you have only the Get-MessageTrackingLog cmdlet.

The Get-MessageTrackingLog cmdlet is a pain in the butt for a few reasons:
  • You need to memorize the syntax. Most of it is pretty straight forward, but you need to remember the correct parameters for searching by sender, recipient, or subject.
  • It only searches the local server by default. Without specifying servers, it only searches the local Exchange server that you're running the tool on. In a lot of cases, you need to see information from all your servers to track it down.
While working on a message delivery problem this week, I wrote up a short script help with simple message tracking based on time, sender, recipient, or message subject. The script is as follows:
 Write-Host "Current Date/Time: $(Get-Date)"  
 $StartTime = Read-Host "Start time for search"  
 $EndTime = Read-Host "End time for search"  
 $SearchType = Read-Host "Search for (S)ender, (R)ecipient, (M)essage subject, or display (A)ll"  
 Switch ($SearchType) {  
   'S' {  
            $Sender = Read-Host "Sender"  
            Get-ExchangeServer | where {$_.isHubTransportServer -eq $true -or $_.isMailboxServer -eq $true} | Get-MessageTrackingLog -Start $StartTime -End $EndTime -Sender $Sender |Select-Object Timestamp,ServerHostname,ClientHostname,Source,EventId,Sender,Recipients,MessageSubject | Out-GridView }  
   'R' {  
            $Recipient = Read-Host "Recipient"  
            Get-ExchangeServer | where {$_.isHubTransportServer -eq $true -or $_.isMailboxServer -eq $true} | Get-MessageTrackingLog -Start $StartTime -End $EndTime -Recipient $Recipient |Select-Object Timestamp,ServerHostname,ClientHostname,Source,EventId,Sender,Recipients,MessageSubject | Out-GridView }  
   'M' {  
            $MessageSubject = Read-Host "Message subject (performs partial matches)"  
            Get-ExchangeServer | where {$_.isHubTransportServer -eq $true -or $_.isMailboxServer -eq $true} | Get-MessageTrackingLog -Start $StartTime -End $EndTime -MessageSubject $MessageSubject |Select-Object Timestamp,ServerHostname,ClientHostname,Source,EventId,Sender,Recipients,MessageSubject | Out-GridView }  
   'A' {  
            Get-ExchangeServer | where {$_.isHubTransportServer -eq $true -or $_.isMailboxServer -eq $true} | Get-MessageTrackingLog -Start $StartTime -End $EndTime |Select-Object Timestamp,ServerHostname,ClientHostname,Source,EventId,Sender,Recipients,MessageSubject | Out-GridView }  
   default {Write-Host "Invalid Option - Run Script Again"}  
 }  
Here is how the script works:
  1. The current date/time are displayed. This shows you the date/time syntax to use for entering time in the next steps.
  2. You are prompted for the time to start searching the logs.
  3. You are prompted for the time to stop searching the logs.
  4. You are prompted for the type of search you want to do: sender, recipient, message subject, or display all.
  5. The switch command uses the $SearchType variable to run a specific code block. The command varies depending on the option, but in general, it prompts for the required information and then runs the query based on it.
  6. Results are displayed by using Out-Gridview. This allows you to sort based on columns.

Notes:

  • This code is used to identify and generate a list of all Exchange servers with message tracking logs which is then piped to the Get-MessageTrackingLog cmdlet.
    Get-ExchangeServer | where {$_.isHubTransportServer -eq $true -or $_.isMailboxServer -eq $true}  
  • When you search by message subject, it returns all results that include the snippet of text. This can make it hard to track down the specific message that you're looking for sometimes. For example, searching for "text" will include messages with "text" in the subject, but also "context","textbook", etc.
  • Only 1000 results are returned by the Get-MessageTrackingLog cmdlet. It's possible to override this, but if your query is returning more than 1000 results, you should probably be refining your query.
  • Times from Exchange 2007 servers seem off. I was testing in a Mixed 2013 and 2007 environment and the content coming back from the 2007 environment had timestamps outside the range I queried. I have not yet had time to investigate, but be aware of this when sorting results based on time.