Pages

Wednesday, December 21, 2016

Migrating Receive Connectors from Exchange 2010 to 2016 with native Exchange PowerShell cmdlets

I’ve been recently involved with a project where I had to assist a client with a Exchange 2010 to 2016 migration and one of the tasks I was assigned to do was to migrate the existing Exchange 2010 Servers receive connectors to the new Exchange 2016 servers:

image

I’ve come across this quite a few times in the past and even wrote a blog post 6 years ago:

How do I export/import Exchange 2007/2010 receive connectors’ allow relay IPs?
http://terenceluk.blogspot.com/2010/11/how-do-i-exportimport-exchange-20072010.html

It has been awhile since I’ve had to do this so I thought there must be a better way of doing this and what seemed to be the popular solution was this this PowerShell script:

COPY EXCHANGE SERVER RECEIVE CONNECTOR
https://www.granikos.eu/en/justcantgetenough/PostId/209/copy-exchange-server-receive-connector

Unfortunately, the script did not work for me as I would receive the following error when attempting to migrate the Exchange 2010 receive connectors to 2016:

[PS] C:\Scripts>.\Copy-ReceiveConnector.ps1 -SourceServer exhc01 -ConnectorName " Anonymous Relay Connector" -Targ
etServer bmexmb01 -MoveToFrontend -ResetBindings -DomainController dc01.domain.com

Security warning
Run only scripts that you trust. While scripts from the internet can be useful, this script can potentially harm your
computer. If you trust this script, use the Unblock-File cmdlet to allow the script to run without this warning
message. Do you want to run C:\Scripts\Copy-ReceiveConnector.ps1?
[D] Do not run  [R] Run once  [S] Suspend  [?] Help (default is "D"): r
At C:\Scripts\Copy-ReceiveConnector.ps1:116 char:13
+ </a>        <a href="/open-source" class="js-selected-navigation-item nav-item n ...
+             ~
The '<' operator is reserved for future use.
At C:\Scripts\Copy-ReceiveConnector.ps1:118 char:13
+ </a>        <a href="/business" class="js-selected-navigation-item nav-item nav- ...
+             ~
The '<' operator is reserved for future use.
At C:\Scripts\Copy-ReceiveConnector.ps1:120 char:13
+ </a>        <a href="/explore" class="js-selected-navigation-item nav-item nav-i ...
+             ~
The '<' operator is reserved for future use.
At C:\Scripts\Copy-ReceiveConnector.ps1:122 char:11
+ </a>      </nav>
+           ~
The '<' operator is reserved for future use.
At C:\Scripts\Copy-ReceiveConnector.ps1:1736 char:225
+ ... hidden" value="&#x2713;" /></div>
+                    ~
The ampersand (&) character is not allowed. The & operator is reserved for future use; wrap an ampersand in double
quotation marks ("&") to pass it as part of a string.
At C:\Scripts\Copy-ReceiveConnector.ps1:1767 char:11
+       <li>&copy; 2016 <span title="0.10192s from github-fe158-cp1-prd.iad.github ...
+           ~
The ampersand (&) character is not allowed. The & operator is reserved for future use; wrap an ampersand in double
quotation marks ("&") to pass it as part of a string.
At C:\Scripts\Copy-ReceiveConnector.ps1:1767 char:23
+       <li>&copy; 2016 <span title="0.10192s from github-fe158-cp1-prd.iad.github ...
+                       ~
The '<' operator is reserved for future use.
At C:\Scripts\Copy-ReceiveConnector.ps1:1767 char:29
+       <li>&copy; 2016 <span title="0.10192s from github-fe158-cp1-prd.iad.github ...
+                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Unexpected token 'title="0.10192s from github-fe158-cp1-prd.iad.github.net">GitHub</span>' in expression or statement.
At C:\Scripts\Copy-ReceiveConnector.ps1:1767 char:100
+ ... ">GitHub</span>, Inc.</li>
+                    ~
Missing argument in parameter list.
At C:\Scripts\Copy-ReceiveConnector.ps1:1786 char:14
+       You can't perform that action at this time.
+              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The string is missing the terminator: '.
    + CategoryInfo          : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : RedirectionNotSupported

[PS] C:\Scripts>

image

I did a bit of troubleshooting and searching but could not find a solution so decided to fall back on the same approach in my older blog post using native Exchange PowerShell cmdlets and a bit of editing of the information in notepad.

Before I begin demonstrating the PowerShell cmdlet and switches to use, let’s begin by reviewing the parameters we’ll be configuring for a receive connector by looking at the options in the EAC:

General Options

image

Note that the parameters available to be configured in the screenshot above are:

  • Name
  • Connector status
  • Protocol logging level
  • Maximum receive message size (MB)
  • Maximum local hop count
  • Maximum hop count

These parameters map to the following PowerShell switches:

Parameter Switch

Name

Name

Connector status

Enabled

Protocol logging level

ProtocolLoggingLevel

Maximum receive message size (MB)

MaxMessageSize

Maximum local hop count

MaxLocalHopCount

Maximum hop count

MaxHopCount

Security Options

image

Note that the parameters available to be configured in the screenshot above are:

  • Authentication
  • Permission Groups

These parameters map to the following PowerShell switches:

Parameter Switch Options

Authentication

AuthMechanism

  • Transport Layer Security (TLS)
    • Enable domain security (mutual Auth TLS)
  • Basic authentication
    • Offer basic authentication only after starting TLS
  • Integrated Windows authentication
  • Externally secured (for example, with IPsec)

Permission Groups

PermissionGroups

  • Exchange servers
  • Legacy Exchange servers
  • Partners
    Exchange users
  • Anonymous users

Scoping Options

image

Note that the parameters available to be configured in the screenshot above are:

  • Remote network settings
  • Network adapter bindings
  • FQDN

These parameters map to the following PowerShell switches:

Parameter Switch

Remote network settings

RemoteIPRanges

Network adapter bindings

Bindings

 

FQDN FQDN

Step #1 – Retrieve and Export Receive Connector Configuration

With the configuration parameters outlined above, the first step for migrating the receive connectors to the new Exchange server is to use the Get-ReceiveConnector to export the receive connectors’ information.  The following is the cmdlet with the switches required:

Get-ReceiveConnector -Server <sourceExchangeServerName> | Select Identity,Name,Enabled,ProtocolLoggingLevel,MaxMessageSize,MaxLocalHopCount,MaxHopCount,AuthMechanism,PermissionGroups,RemoteIPRanges,Bindings,FQDN

The cmdlet above will output something similar to the following:

image

Notice that the RemoteIPRanges configuration output gets truncated when the list has more than 16 entries which means if the list has less than 16, you’re set to go but if you have more then you’ll have to execute the following before using the Get-ReceiveConnect cmdlet:

$FormatEnumerationLimit =-1

Get-ReceiveConnector -Server <sourceExchangeServerName> | Select Identity,Name,Enabled,ProtocolLoggingLevel,MaxMessageSize,MaxLocalHopCount,MaxHopCount,AuthMechanism,PermissionGroups,RemoteIPRanges,Bindings,FQDN

image

The cmdlets above will list all of the IPs:

image

Now that we have the cmdlets to export all of the information, proceed to pipe the output to a text file:

$FormatEnumerationLimit =-1

Get-ReceiveConnector -Server <sourceExchangeServerName> | Select Identity,Name,Enabled,ProtocolLoggingLevel,MaxMessageSize,MaxLocalHopCount,MaxHopCount,AuthMechanism,PermissionGroups,RemoteIPRanges,Bindings,FQDN > C:\ReceiveConnectorsExport.txt

image

For the parameter options of the Get-ReceiveConnector cmdlet, refer to the following TechNet article: https://technet.microsoft.com/en-us/library/aa998618(v=exchg.160).aspx

Step #2 – Extract configuration and create new Receive Connector

With the information in the text file we created above, proceed to extract the information, format them properly and use the following cmdlet to create the new receive connector:

New-ReceiveConnector -Name “<NameOfReceiveConnector” -Enabled $true –ProtocolLoggingLevel <verbose or none> –MaxMessageSize <numberMB> -MaxLocalHopCount <number> –MaxHopCount <number> –AuthMechanism <authentication> –PermissionGroups <groups> -RemoteIPRanges x.x.x.x,.x.x.x.x -Bindings 0.0.0.0:25 -FQDN <FQDN for connector> -Server <targetServerName> -TransportRole FrontendTransport

Items to consider for the New-ReceiveConnector cmdlet:

  • You have to remove custom if it is in the PermissionsGroups configuration output
  • You have to add the TransportRole switch with FrontendTransport parameter at the end for Exchange 2013 and 2016 target servers
  • The FQDN may need to change depending on the name used
  • Adjust the bindings IP address if the source configuration uses a specific IP address that is not configured on the target server

For the parameter options of the New-ReceiveConnector cmdlet, refer to the following TechNet article: https://technet.microsoft.com/en-us/library/bb125139(v=exchg.160).aspx

The follow is an example of the cmdlet with parameters:

New-ReceiveConnector -Name “Anonymous Relay Connector” -Enabled $true -ProtocolLoggingLevel verbose -MaxMessageSize 10MB -MaxLocalHopCount 8 -MaxHopCount 60 -AuthMechanism Tls -PermissionGroups AnonymousUsers -RemoteIPRanges 10.21.1.110,10.5.1.3,10.22.1.212,10.22.1.41,10.22.1.68,10.22.1.210,10.22.1.211,10.22.1.157,10.22.1.10,10.22.1.159,10.22.1.25,192.168.60.28,10.34.30.222,10.20.1.75,10.22.1.164,10.23.0.79,10.22.1.37,10.2.1.37,10.22.1.233,10.23.0.19,10.22.1.49,10.34.30.26,10.21.1.142,10.20.1.64,10.43.3.140,192.168.60.172,10.20.1.50,10.21.1.101,10.20.1.83,10.21.1.117,10.23.0.60,192.168.60.158,10.20.1.175,10.21.1.174,192.168.60.162,10.31.30.22,10.23.0.54,10.22.1.51,10.21.1.41,10.20.1.189,10.20.1.162,10.5.8.242,10.21.1.130,10.21.1.10,10.34.10.30,10.5.3.21,10.20.1.174,10.7.3.11,10.7.3.4,10.7.3.8,10.7.3.3,10.20.1.47,10.21.1.111,10.21.1.92,10.22.1.131,10.21.1.26,10.21.1.24,10.21.1.25,10.21.1.23,10.21.1.22,10.34.30.221,10.21.1.51,10.6.3.92,10.6.3.91,10.6.3.53,192.168.60.56,192.168.60.102,10.34.170.60,10.21.1.49,10.34.30.17,10.21.1.48,10.20.1.126,10.20.1.30,10.34.10.11,10.34.10.20,10.34.10.21,10.34.10.10,10.21.1.60,10.21.1.88,192.168.60.58,10.21.1.54,10.20.1.72,10.43.3.80,10.43.3.81,10.21.1.52,10.20.1.181,192.168.60.48,10.20.7.177,192.168.60.183,10.3.2.10,10.20.2.15,192.168.60.127,192.168.60.205,192.168.60.174,192.168.60.104,192.168.60.173,192.168.60.191,10.3.3.203,192.168.60.169,192.168.60.108,192.168.60.55,192.168.170.60,192.168.60.170,192.168.170.30,192.168.60.106,192.168.70.152,192.168.60.198,192.168.60.189,10.3.3.200,192.168.60.185,192.168.70.148,192.168.60.9,192.168.170.125,192.168.170.128,192.168.60.91,192.168.60.148,192.168.170.26,192.168.60.135,192.168.60.24,192.168.60.21,192.168.60.19,192.168.160.136,192.168.60.57,192.168.170.147,192.168.60.8,192.168.60.160,192.168.173.10,192.168.60.124,192.168.160.129,192.168.20.28,192.168.200.0/24,192.168.100.0/24 -Bindings 0.0.0.0:25 -FQDN EXHC01.domain.com -Server bmexmb01 -TransportRole FrontendTransport

image

Monday, December 19, 2016

“Skype for Business Server 2015, Backup Service central management backup module has backup data that never gets imported by backup pool.” is logged on primary server referencing the backup server

Problem

You’ve recently failed over the CMS and pool from a primary Skype for Business Server 2015 to a backup server then failed the services back to the primary server but started noticing the following errors logged on the primary active server with the contents referencing the backup server:

Log Name: Lync Server

Source: LS Backup Service

Event ID: 4098

Level: Error

Skype for Business Server 2015, Backup Service central management backup module has backup data that never gets imported by backup pool.

Backup data file: \\drlyncstd01.domain.com\LyncShare\2-BackupService-1\BackupStore\CentralMgmt\CMSMaster\Data\Backup.zip
Cause: Import issue in the backup pool. Please check event log of Skype for Business Server 2015, Backup Service in the backup pool for more information.
Resolution:
Fix import issue in the backup pool

image

image

Note that the content in the error log references the backup / disaster recovery server but the event is logged on the primary active server.

The backup / disaster recovery server also has the Skype for Business Server Master Replicator Agent service stopped.  You can start the service but it will stop after a few minutes:

image

Solution

I’ve noticed this happening in most SfB environments that have experienced a planned or unplanned failover of the CMS and/or pool.  To correct the issue, simply launch the Skype for Business Server 2015 – Deployment Wizard on the backup / disaster recovery server, navigate into the Install or Update Skype for Business Server System menu:

image

… and then run both the:

  • Install Local Configuration Store
  • Setup or Remove Skype for Business Server Components

image

Once the above have successfully completed, the Skype for Business Server Master Replicator Agent service should now start and stay running:

image

The event ID 4098 error should no longer be logged:

image

… and an event ID 4099 information log should be written indicating:

Import issue in the backup pool was fixed. Skype for Business Server 2015, Backup Service central management backup module export operation continues now.

image

image

Thursday, December 15, 2016

Migrating Skype for Business Server 2015 CMS from one server to another

I recently had to migrate and decommission a Skype for Business Server after upgrading it from Lync Server 2013 and noticed that the Windows 2012 Server would continuously blue screen every few hours.  One of the tasks involved with the migration was to move the CMS (Central Management Server) from the to-be-decommissioned server to the newly one and this post serves to demonstrate the process.

Note that the CMS is currently on the lyncstd01.domain.bm server:

image

image

Note the newly deployed lyncstd02.domain.bm that we will be moving the CMS to:

image

Begin by backing up the Skype for Business configuration with the following cmdlets:

Export-CsConfiguration -FileName C:\SfB-config.zip

Export-CsLisConfiguration -FileName C:\SfB-lis.zip

image

image

With the backup completed, run the Prepare first Standard Edition server wizard in the Skype for Business Server 2015 – Deployment Wizard on the CMS destination server (lyncstd02):

image

image

image

image

Once the wizard has completed, launch the Skype for Business Server Management Shell on the CMS destination server and execute the following:

Install-CsDatabase -CentralManagementDatabase -SQLServerFQDN <FQDN of your Standard Edition Server> -SQLInstanceName <name of instance - RTC by default>

The cmdlet executed in the screenshot below is:

Install-CsDatabase -CentralManagementDatabase -SQLServerFQDN lyncstd02.domain.bm -SQLInstanceName RTC

image

image

Once the cmdlet completes enable the topology with:

Enable-CsTopology

image

image

With the topology published, execute Move-CsManagementServer to move the Central Management Server to the destination server:

image

image

image

Note the following warning message once the cmdlet completes:

Warning: The move completed successfully but the following additional steps are required:

Run local setup on the following computers to remove Central Management services that are no longer defined in the topology:

- lyncstd01.domain.bm

Reviewing the html log will show the same warning message in the management shell:

image

Continue to run the Install or Update Skype for Business Server System on the new server hosting CMS:

image

Run the Setup or Remove Skype for Business Server Components wizard again:

image

image

image

image

Once the wizard completes, continue by running the Install or Update Skype for Business Server System on the old server that use host the CMS:

image

Run the Setup or Remove Skype for Business Server Components wizard:

image

image

image

There may be times when the wizard will complete but also throw the error:

Command execution failed: ###50021:XdsPublishItems:This central management store has moved to another location. No more changes can be made to this store.

image

Confirm that replication is successful by executing the cmdlet Get-CsManagementStoreReplicationStatus:

image

There may be times when replication does not appear to be working and the UpToDate variable never changes to True.  If this happens, check the Skype for Business Server File Transfer Agent service on both servers because sometimes it is stopped:

image

Restarting the services and rerunning the Get-CsManagementStoreReplicationStatus should show that all of the UpToDate variables is shown as True:

image

The CMS should now be moved and the Skype for Business Topology Builder should reflect the changes:

image

If the old server hosting the CMS is going to remain in the environment and you would like to remove the Central Management store files then execute the following:

Uninstall-CsDatabase -CentralManagementDatabase -SqlServerFqdn <FQDN of SQL Server> -SqlInstanceName <Name of source server>

**Note that it is important not to proceed with the removal of the previous database files until replication is complete and is stable. If you remove the files prior to completing replication, you will disrupt the replication process and leave the newly moved Central Management Server in an unknown state.

The following is an example of executing the cmdlet:

Uninstall-CsDatabase -CentralManagementDatabase -SqlServerFqdn lyncstd01.domain.bm -SqlInstanceName RTC

image

Once the cmdlet completes run the Setup or Remove Skype for Business Server Components wizard:

image

image

With the above completed, the Skype for Business Server Master Replicator Agent will no longer be present:

imageimage