Skip to content

Exchange 2016 – Migration of existing, custom Receive Connectors from Exchange 2010 to 2016 results in multiple errors

Another Exchange 2016 migration, another error while trying to migrate custom Receiver Connectors from Exchange 2010 to 2016 ...  an analysis.

Courtesy of Shane Jackson it was easy to copy Receive Connectors from Exchange 2010 to Exchange 2013.  The following Powershell lines will help you with that:

# pipe old Receiver Connectors except Default as well as Client into an array
[array]$ReceiveConnectors = Get-ReceiveConnector -Server $OldServer | Where {$_.Name -notlike “Default $($OldServer)” -and $_.Name -notlike “Client $($OldServer)”}
# create new Receive Connectors - WhatIf
$ReceiveConnectors | foreach {
New-ReceiveConnector -Name $_.Name -RemoteIPRanges $_.RemoteIPRanges -bindings $_.Bindings -Banner $_.Banner -ChunkingEnabled $_.ChunkingEnabled -DefaultDomain $_.DefaultDomain -DeliveryStatusNotificationEnabled $_.DeliveryStatusNotificationEnabled -EightBitMimeEnabled $_.EightBitMimeEnabled -DomainSecureEnabled $_.DomainSecureEnabled -LongAddressesEnabled $_.LongAddressesEnabled -OrarEnabled $_.OrarEnabled -Comment $_.Comment -Enabled $_.Enabled -ConnectionTimeout $_.ConnectionTimeout -ConnectionInactivityTimeout $_.ConnectionInactivityTimeout -MessageRateLimit $_.MessageRateLimit -MaxInboundConnection $_.MaxInboundConnection -MaxInboundConnectionPerSource $_.MaxInboundConnectionPerSource -MaxInboundConnectionPercentagePerSource $_.MaxInboundConnectionPercentagePerSource -MaxHeaderSize $_.MaxHeaderSize -MaxHopCount $_.MaxHopCount -MaxLocalHopCount $_.MaxLocalHopCount -MaxLogonFailures $_.MaxLogonFailures -MaxMessageSize $_.MaxMessageSize -MaxProtocolErrors $_.MaxProtocolErrors -MaxRecipientsPerMessage $_.MaxRecipientsPerMessage -PermissionGroups $_.PermissionGroups -PipeliningEnabled $_.PipeLiningEnabled -ProtocolLoggingLevel $_.ProtocolLoggingLevel -RequireEHLODomain $_.RequireEHLODomain -RequireTLS $_.RequireTLS -EnableAuthGSSAPI $_.EnableAuthGSSAPI -ExtendedProtectionPolicy $_.ExtendedProtectionPolicy -SizeEnabled $_.SizeEnabled -TarpitInterval $_.TarpitInterval -Server $NewServer -WhatIf
}

But with Exchange 2016 those handy Powershell lines won't help you anymore as executing those results in multiple errors:

1st error, due to multiple Receive Connectors listening on port 25:

The values that you specified for the Bindings and RemoteIPRanges parameters conflict with the settings on Receive connector "<Server>\Default Frontend
<Server>". Receive connectors assigned to different Transport roles on a single server must listen on unique local IP address & port bindings.
+ CategoryInfo : InvalidOperation: (<Server>\Anonymous <Server>:ReceiveConnector) [New-ReceiveConnector], ReceiveConnectorRoleConflictExcept
ion
+ FullyQualifiedErrorId : [Server=<Server>,RequestId=b5f0fc88-538c-49a3-9a8f-9a279fc29e37,TimeStamp=17.01.2018 15:00:24] [FailureCategory=Cmdlet-Receiv
eConnectorRoleConflictException] 8B5C879,Microsoft.Exchange.Management.SystemConfigurationTasks.NewReceiveConnector
+ PSComputerName : <Server>

2nd error, which is sort of specific for my environment, as there were some Custom permissions in place on the Receive Connector being migrated from Exchange 2010 to Exchange 2016:

You can't use Custom to specify PermissionGroups.
+ CategoryInfo : InvalidOperation: (<Server>\Relay <Server>:ReceiveConnector) [New-ReceiveConnector], CustomCannotBeS...GroupsException
+ FullyQualifiedErrorId : [Server=<Server>,RequestId=b5f0fc88-538c-49a3-9a8f-9a279fc29e37,TimeStamp=17.01.2018 15:00:24] [FailureCategory=Cmdlet-Custom
CannotBeSetForPermissionGroupsException] 22111502,Microsoft.Exchange.Management.SystemConfigurationTasks.NewReceiveConnector
+ PSComputerName : <Server>

Now let's try the clarify those errors in get rid of them step by step:

1st error: 

Courtesy of Mark Gossa:
"If you want to create a new receive connector that listen on port 25, you can do this but you have to create them it using the Frontend Transport role if you have either an Exchange 2016 server or an Exchange 2013 server with both the CAS and MBX roles installed on the same server."

This can be achieved by using the TransportRole switch with the -FrontendTransport parameter of the New-ReceiveConnector  cmdlet, e.g.:

New-Receiveconnector -Name "Custom Receive Connector" -RemoteIPRange (“10.10.61.176/32”) -TransportRole "FrontendTransport" -Bindings ("0.0.0.0:25") -usage "Custom" -Server $ENV:localhost

As soon as the custom Receive Connectors have been successfully added we can configure required custom permissions.

2nd error: What are Custom permissions in terms of Receive Connectors?

With Exchange Receive Connectors you can apply different permission settings. But as soon as you apply dedicated AD permissions for a certain user to a Receive Connector, i.e. 

  • ms-Exch-SMTP-Submit
  • ms-Exch-Bypass-Anti-Spam
  • ms-Exch-SMTP-Accept-Any-Recipient
  • et al

via the -ExtendedRights parameter of the Add-ADPermission cmdlet, the PermissionsGroup property will be set to Custom, e.g.

Get-ReceiveConnector "SERVER2016\Custom Receive Connector" | Add-ADPermission -User DOMAIN\SpecialUser -ExtendedRights ms-Exch-SMTP-Submit,ms-Exch-Bypass-Anti-Spam,ms-Exch-SMTP-Accept-Any-Recipient

In order to copy those custom AD permissions from an existing Receive Connector to a new Receive Connector destined for Exchange 2016, you first have to identify them by running:

Get-ReceiveConnector "SERVER2010\Custom Receive Connector" | Get-ADPermission | ? {$_.ExtendedRights} | ? {[string]$_.ExtendedRights -like "Ms-Exch*"} | select identity,user,extendedrights

The result might look something like this:

Relay permissions are an Active Directory permission and not an Exchange permission. Thus most of these settings are easy to identify and copy, except the ability of a Receive Connector to perform as an external relay which is configured using the ms-Exch-SMTP-Accept-Any-Recipient extended AD permission which is not so visible. In order to reduce the output of the aforementioned cmdlet the following EMS one-liner is useful. It helps to determine which receive connectors in the organization are open relay connectors so you can configure the new ones likewise:

Get-ReceiveConnector | Get-ADPermission | where {$_.identity -notlike "*Default*" -and $_.identity -notlike "*Client*" -and $_.user -like "NT AUTHORITY\*" -and $_.ExtendedRights -like "MS-Exch-SMTP-Accept-Any-Recipient"} | select identity, user, ExtendedRights

The result might look something like this where I identified two custom Receive Connectors for open relaying:

Custom permissions can also be viewed in the configuration portion of the AD schema using ADSIEdit. The Receive Connectors can be found under:

CN=Custom Receive Connector,CN=SMTP Receive Connectors,CN=Protocols,CN=SERVER2010,CN=Servers,CN=Exchange Administrative Group (FYDIBOHF23SPDLT),CN=Administrative Groups,CN=MYORG,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=domain,DC=local

Now you can add identified and required permissions to your custom Receive Connector, i.e. if you need to be able to send mail outside your organization you will need to add the MS-Exch-SMTP-Accept-Any-Recipient permission by executing:

Get-ReceiveConnector "SERVER2016\Custom Receive Connector" | Add-ADPermission -User 'NT AUTHORITY\Anonymous Logon' -ExtendedRights MS-Exch-SMTP-Accept-Any-Recipient

Further reading:

Leave a Reply