.

📅Cross-Forest Free/Busy with Meeting Rooms: Making It Work in Exchange

🧩Introduction

Two previous posts discussed Free / Busy (Availability information) in cross-forest scenarios:

🔗Cross Forest Free / Busy in Exchange Server Environment via Availability Address Space and Calendar Delegation

🔗Cross Forest Free / Busy in Exchange Server Environment via Federation Trust

In addition to the information described there, I would like to mention some specific scenario, when users need to see availability of meeting rooms, located in different forest.

Assume, that availability is configured according to one of the scenarios that looks more appropriate (via Federation Trust or Availability Namespace).

✅ How users work with meeting rooms

The difference between a regular mailbox and room mailbox (meeting rooms) should be obvious.  From user perspective – it’s a specific object in GAL and also located in dedicated address list (by default, “All Rooms” address list contains all room mailboxes). This object describes important properties of a meeting room, like capacity.

When a user wants to find an appropriate meeting room for his meeting, he uses a scheduling assistant and room finder to locate rooms that are appropriate and available for desired time. All that means, that most likely you will need to create corresponding mail enabled object in another organization for your room mailbox and group / organize them with room lists, despite on a method used to configure availability between forests.

Another thing – when a user books a meeting room (create meeting requests), a message will be sent to room mailbox in another organization. This message should be delivered and processed accordingly.

✅ Create appropriate mail enabled objects.

Assume, that we have 2 organizations called Contoso.com and Sols.com. We want that room mailbox cont_room1 in contoso.com would be available for user sols1 in sols.com.

1.Consider that we’re interested in per-user availability and configured that via availability service with Active Directory trust. In that case, we need to create a specific object (mail contact or user) with properties corresponding to the original object.

2. Let’s get these properties (of cause, you would probably like to copy another property, like phone number, location and so on):

get-mailbox sols1@sols.com | fl displayname, LegacyExchangeDN, emailaddresses

Get-ADUser (get-mailbox sols1@sols.com).DistinguishedName | ft SID

3. Create MailUser with values we’ve got on previous step. In case sols1 user doesn’t have a need to be a delegate of room mailbox (i.e. open calendar, edit meetings and so on), you can create mail contact for that. For more details visit 🔗Cross Forest Free / Busy in Exchange Server Environment via Availability Address Space and Calendar Delegation The same process is for availability configured via Federation Trust, as this option doesn’t allow to configure delegate and extended opportunities.

New-MailUser sols1  -ExternalEmailAddress  sols1@sols.com -Alias Branch-user  -DisplayName sols1 -UserPrincipalName sols1@sols.com -PrimarySmtpAddress sols1@sols.com

 Get-ADObject -Filter “sAMAccountName -eq ‘sols1″ | Set-ADObject -Replace @{mAPIRecipient=”TRUE”;msExchMasterAccountSid=”S-1-5-21-1264642549-4058670248-589901444-101602″;msExchRecipientDisplayType=”-1073741818″;msExchRecipientTypeDetails=”128″;proxyAddresses=@(“x500:/o=SOLS/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=7de3c87f0fe54f56a907dab9f2b11aa7-sols1″,”SMTP:sols1@sols.com”);mail=sols1@sols.com;targetAddress=”SMTP: sols1@sols.com”;msExchOriginatingForest=”sols.com”}

You need to add LegacyExchangeDN from previous steps to the addresses as x500 addresses, and SID to msExchMasterAccountSid. Correctly replace names and mailing addresses.

4. Next, disable this account as it want be used directly:

Disable-ADAccount sols1

📌Create mail enabled object for meeting room in sols.com.

  1. Verify required attributes for meeting room in contoso.com (add another optional one if you need it):

Get-ADUser (get-mailbox cont_room1).DistinguishedName | ft SID

get-mailbox cont_room1| fl LegacyExchangeDN,emailaddresses, *capaci*

2. As we suppose that no need to open calendars of other user’s from meeting room account, it’s enough to create mail contact. Also, we don’t expect to delegate per-user availability for meeting room account, so no need to copy and set SID as msExchMasterAccountSid. But just in case we will do that like for normal user account.

New-MailContact -DisplayName “Room1 in Contoso Organization” -Name cont_room1 -ExternalEmailAddress cont_room1@contoso.com -Alias cont_room1

Get-MailContact hq-room | Set-MailContact -EmailAddressPolicyEnabled $false

Get-ADObject -Filter “cn -eq ‘cont_room1″ | Set-ADObject -Replace @{mAPIRecipient=”TRUE”;msExchMasterAccountSid=”S-1-5-21-3083106029-26891345-206432988-1173″;msExchRecipientDisplayType=”-2147481850″;msExchRecipientTypeDetails=”16″;proxyAddresses=@(“/o=CONTOSO/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=a31820be5d1f4003932e538c8e6404f7-cont_room1″,”SMTP: cont_room1@contoso.com”);mail= cont_room1@contoso.com;msExchOriginatingForest=”contoso.com”;msExchResourceCapacity=”15″}

💡Note. msExchRecipientDisplayType is equal to -2147481850 that corresponds to MailUser (RemoteRoomMailbox).

msExchRecipientTypeDetails = 16 corresponds to RoomMailbox

For more information about different types you can visit this great article https://answers.microsoft.com/en-us/msoffice/forum/all/recipient-type-values/7c2620e5-9870-48ba-b5c2-7772c739c651

📌Create a room list, if you need one:

New-DistributionGroup -Name “HQ Conference Rooms”  -RoomList

Add-DistributionGroupMember -Identity “HQ Conference Rooms”  -Member ‘cont_room1@contoso.com’

And update address list in both organizations:

Get-AddressList “All Contacts” | Update-AddressList

Get-AddressList “All Users” | Update-AddressList

Get-AddressList “All Rooms” | Update-AddressList

Optionally you can also update global address list and offline address book:

Get-GlobalAddressList | Update-GlobalAddressList

Get-OfflineAddressBook | Update-OfflineAddressBook

📌Verify calendar availability for room mailbox.

You can create a meeting from a test user, verify that a room exists in All Rooms list and availability information can be seen for this room list.

You can also  provide extended availability information for room mailbox calendar:

set-MailboxFolderPermission -Identity cont_room1@contoso.com:\Calendar -User Default  -AccessRights LimitedDetails

You should now see information about the subject and organizer.

📌Accept invites

By default, messages that are sent between 2 different organizations are sent anonymously. In that case, you should also modify appropriate permissions and change calendar permissions, so invites that are sent from external organization would be processed automatically:

Set-CalendarProcessing cont_room1 -AutomateProcessing AutoAccept -ProcessExternalMeetingMessages $true

If you want to prohibit senders from internet to send messages to this room mailbox, you can create a transport rule or block such messages on 3d party mail gateway.

📌Create dedicated connectors

As alternative option to previous point, you can create dedicated connectors between 2 organizations, so messages will be sent directly between organizations and considered as authenticated.

💡Note. Be careful with this option, as this method allows extended permissions for such messages (i.e. sender will be resolved in address list and considered as trusted \ internal and etc.)          

Consider, we have 2 servers in Contoso organization: CONT-MBX1 with IP address 10.0.1.1 and CONT-MBX2 with address 10.0.1.2. In SOLS organization we also have 2 servers  – SOLS-MBX1 with IP address 10.0.2.1 and SOLS-MBX2 with IP address 10.0.2.2. We suppose that interaction via smtp is done via port 25.

1. Create receive connector in HQ (do this for both servers):

New-ReceiveConnector -Name From_Branches -Server CONT-MBX2  -TransportRole FrontEndTransport -TarpitInterval 00:00:00 -PermissionGroups AnonymousUsers, ExchangeServers -AuthMechanism Tls, ExternalAuthoritative -RemoteIPRanges 10.0.2.1, 10.0.2.2  -Enabled $false -MaxMessageSize 35MB -ProtocolLoggingLevel Verbose -Bindings 0.0.0.0:25

In this example we set TarpitInterval to 0, thus, minimize delays for message delivery, but that’s optional. Also, the connector has a message size limitation 35MB and logging is enabled. This connector will be disabled. If you’re sure that all parameters look good, you can enable this connector.

To check connector availability, you can use telnet from SOLS servers (we expect no inspection from network devices). After you will issue EHLO command you will see appropriate command list of available commands:

220 CONT-MBX1.hq.com Microsoft ESMTP MAIL Service ready at Tue, 28 Nov 2023 12:57:42 +0000

EHLO sols.com

250 CONT-MBX1.hq.com Hello [10.0.0.21]

250-SIZE 37748736

250-PIPELINING

250-DSN

250-ENHANCEDSTATUSCODES

250-STARTTLS

250-8BITMIME

250-BINARYMIME

250-CHUNKING

250 SMTPUTF8

2.  Сreate send connector in SOLS:

New-SendConnector -Name “TO_CONTOSO” -SmartHosts 10.0.1.1, 10.0.1.2  -DNSRoutingEnabled $false -Enabled $false -MaxMessageSize 35MB -SourceTransportServers SOLS-MBX1, SOLS-MBX2 -ProtocolLoggingLevel Verbose  -AddressSpaces contoso.com

3. Repeat 1-2 for both organizations.

4. Now you can send a message between both organizations and verify message headers. If you see this, than everything is configured correctly:

X-MS-Exchange-Organization-AuthAs: Internal

X-MS-Exchange-Organization-AuthMechanism: 10

In this case, you don’t need to set CalendarProcessing’ ProcessExternalMeetingMessages parameter to $true.

✅Summary

  1. You should customize the commands above for your exact needs.
  2. Select an appropriate option for transport according to your needs.
  3. You can use appropriate tools to sync contacts between organizations.

End.


Leave a comment