Post by David on Aug 13, 2012 20:03:59 GMT 5.5
Upgrade Exchange 2003 to Exchange 2010
Exchange 2010 contains a lot of compelling new features such as the new High Availability, the facility to store your Exchange databases on JBOD (Just a Bunch of Disks), the archiving option and the new Outlook Web App and do not forget the new Windows Mobile 6.5 and its new mail client.
If you have an Exchange Server 2003 environment you may want to skip Exchange Server 2007 and move directly to Exchange Server 2010. The easiest way to achieve this is to integrate Exchange Server 2010 into the existing Exchange Server 2003 environment, a so called intra-organizational migration. This is also known as transitioning from Exchange Server 2003 to Exchange Server 2010.
Exchange Server 2003
Suppose we have a fictitious company called Inframan, which is a consulting company specializing in bridges, tunnels, buildings etc. Inframan has approximately 500 employees, 50 employees are working in the office, 450 employees are working ‘in the field’. Employees within the office have their own desktop which connects to an Exchange 2003 Mailbox Server using Outlook 2003 and Outlook 2007. Employees outside the office connect to the office using their company laptop with Outlook and with Windows Mobile devices. When needed they can use their PC at home to use Outlook Web Access to access their mailbox. Typical usage profile is “light”, approximately 25 messages are received per day and 10 messages are sent per day, per user that is. Behind the firewall is an ISA Server 2006 acting as a reverse proxy to publish all Exchange Services to the Internet. Inframan’s environment will look something like this:
Inframan is using only one namespace for accessing all services from the Internet: webmail.inframan.nl. This is used for Outlook Web Access, Outlook Anywhere(RPC over HTTP) and Windows Mobile devices.
Recently Inframan has been thinking about upgrading to Exchange Server 2007, but they decided to move directly to Exchange Server 2010.
Coexistence with Exchange Server 2010
Exchange Server 2010 can easily coexist in a Exchange Server 2003 organization as long as the Exchange Server 2010 prerequisites are met:
•The Active Directory forest needs to be in Windows Server 2003 forest functionality mode;
•All domains that contain Exchange recipients need to be in Windows Server 2003 domain native mode;
•The Global Catalog Servers and the Active Directory Schema Master need to be at a minimum level of Windows Server 2003 SP1 (which equals to Windows Server 2003 R2);
•The Exchange 2003 organization needs to be running in ‘native mode’;
•Link State updates on all Exchange Server 2003 servers need to be disabled according to Microsoft knowledge base article 'Suppress Link State Updates'
Suppress Link State Updates
2 out of 2 rated this helpful - Rate this topic
Applies to: Exchange Server 2010 SP2
Topic Last Modified: 2011-04-28
This topic explains how to use Registry Editor to suppress propagation of minor link state updates between routing groups in Microsoft Exchange Server 2010 and Exchange Server 2003.
We recommend that you perform this procedure if the following conditions are true:
You have installed the Exchange 2010 Hub Transport server role in an existing Exchange 2003 organization. For more information about this step, see Install Exchange 2010 in an Existing Exchange 2003 Organization.
The existing Exchange organization includes more than one Exchange 2003 routing group.
You will configure more than one routing group connector between Exchange 2003 routing groups and Exchange 2010.
The first routing group connector is created when the first Hub Transport server role is installed on a computer in the Exchange organization. Before you create additional routing group connectors, perform this procedure on every Exchange 2003 server in the organization. When you suppress minor link state updates, the servers running Exchange 2003 don't mark connectors as unavailable. This procedure makes sure that earlier versions of Exchange only use least cost routing and don't try to calculate an alternative route.
The purpose of this procedure is to make sure that routing loops can't occur. Exchange 2010 doesn't use a link state routing table and doesn't support relay of link state information. If you don't suppress minor link state updates, routing loops may occur. For more information about how routing occurs in an Exchange organization that includes Exchange 2010 servers and Exchange 2003 servers, see Upgrade from Exchange 2003 Transport.
Caution:
Incorrectly editing the registry can cause serious problems that may require you to reinstall your operating system. Problems resulting from editing the registry incorrectly may not be able to be resolved. Before editing the registry, back up any valuable data.
Suppress Link State Updates on Exchange 2003
--------------------------------------------------------------------------------
To perform this procedure, you must log on to the Exchange 2003 server by using an account that is delegated membership in the local Administrators group.
1.Open Registry Editor.
2.Locate HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\RESvc\Parameters.
3.Right-click Parameters and select New | DWORD value. Name the new DWORD value SuppressStateChanges.
4.Double-click SuppressStateChanges.
5.In the Value data field, enter 1.
6.Close Registry Editor, and then restart the SMTP service, the Microsoft Exchange Routing Engine service, and the Microsoft Exchange MTA Stacks services for the change to take effect.
Inframan will build two new Exchange Server 2010 servers, one combined Hub Transport Server / Client Access Server and one dedicated Mailbox Server. These Servers will be installed in the same Windows Server 2003 Active Directory domain as the Exchange Server 2003 organization. This will greatly improve the ease of moving mailbox from Exchange Server 2003 to Exchange Server 2010.
Moving from Exchange Server 2003 to Exchange Server 2010 in the same Active Directory forest is called transitioning. Building a new Active Directory forest with a new Exchange Server 2010 organization and moving mailboxes from the old Active Directory to the new Active Directory is called migrating.
The interim messaging environment, where both Exchange Server 2003 and Exchange Server 2010 coexist in the same Active Directory domain will look like this:
In Exchange Server 2007 Internet clients could connect to the Exchange Server 2007 Client Access Server while the mailbox was still on Exchange Server 2003. The Client Access Server retrieves the data out of the mailbox and sends it back to the Internet client. In Exchange Server 2010 this has changed. When a client connects to Exchange Server 2010, it actually connects to the Exchange Server 2010 Client Access Server and if the mailbox is still on the Exchange Server 2003 Mailbox Server then the client is redirected to the Exchange Server 2003 front-end server. This front-end server then handles the connection request. This automatically means the namespaces of the Exchange environment will change. For Inframan this means that the following namespaces are used:
•https://webmail.inframan.nl – This is used by all Internet clients that connect to the Exchange environment. This name is not different than in the Exchange Server 2003 namespace, but it will now point to the Exchange Server 2010 Client Access Server;
•https://autodiscover.inframan.nl – This is used by Outlook 2007 and (Outlook 2010) clients for autodiscover purposes;
•legacy.inframan.nl – This will be the new namespace for the Exchange Server 2003 front-end server. This automatically means that the namespace for the Exchange Server 2003 front-end server is going to change!
The servers that will hold the Exchange Server 2010 server roles have the following prerequisites:
•The servers need to be running on Windows Server 2008 or Windows Server 2008 R2;
•.Net framework 3.5 with SP1 needs to be installed;
•PowerShell 2.0 needs to be installed;
•Office 2007 Filter packs needs to be installed for the Hub Transport Server role and the Mailbox Server role;
Make sure that after installing Windows on the servers that they are up-to-date with the latest hotfixes and service packs.
The first step for Exchange Server 2010 Server is to upgrade the Active Directory schema to contain the Exchange Server 2010 extensions. This is achieved by using the Exchange Server 2010 setup application followed by a number of parameter:
Setup.com /PrepareLegacyExchangePermissions – Exchange Server 2003 uses the Recipient Update Service to stamp the user with the appropriate Exchange attributes during provisioning. This is replaced in Exchange Server 2010 by E-Mail Address Policies. The /PrepareLegacyExchangePermissions parameter changes security settings so that both the Recipient Update Service and E-mail Address Policies can coexist in the same Active Directory;
Setup.com /PrepareSchema – This command upgrades the Active Directory schema to include the Exchange Server 2010 extensions. This can be checked by using ADSIEDit and checking the value of the UpperRange parameter of the CN=ms-Exch-Schema-Version-Pt object in the Schema. This should have one of the following values:
Note that the value is the same in Exchange Server 2007 service pack 2 and in Exchange Server 2010 RTM – this is because Exchange Server 2007 service pack 2 will install the Exchange Server 2010 schema extensions.
Setup.com /PrepareAD – This command upgrades the Exchange organization, which is stored in the configuration partition in Active Directory to support Exchange Server 2010. In Exchange Server 2003 information is stored in the “First Administrative Group” or perhaps more if you created additional Administrative Groups. The Exchange Server 2010 setup application will create a new Administrative Group called “Exchange Administrative Group (FYDIBOHF23SPDLT)” where all Exchange Server 2010 configuration information is stored. This will be visible in the Exchange Server 2003 System Manager:
Setup.com /PrepareDomain – This is the last step in preparing the Active Directory and will create all necessary groups in the domain being prepared.
When Active Directory is fully prepared we can continue with installing the first Exchange Server 2010 server in the environment. For our example, this has to be the combined Hub Transport and Client Access Server. Start the graphical setup program (setup.exe) and download the Language File bundle if needed. If you select “install only languages from the DVD” only the language setting of your DVD (for example English or French) will be available. This is used not only for the language of the Exchange Server, but also the available language settings for the clients being used.
During the installation of the combined Hub Transport and Client Access Server a so called ‘custom setup’ will be used. This means we can select which server roles will be installed. In the Inframan example the following needs to be selected during setup:
When continuing the setup application a window will be shown asking if this Client Access Server is Internet facing and if so, what the external domain will be. This is an important step because it configures the Client Access Server automatically with the appropriate settings. Check the “The Client Access server will be Internet-facing” option and enter the external domain name. This is “webmail.inframan.nl” in our example
Exchange Server 2003 uses Routing Groups to determine the proper way to route messages while Exchange Server 2010 uses Active Directory sites for routing. These are not compatible with each other so a legacy Routing Group Connector will be created within Exchange Server 2010. This legacy connector connects Exchange Server 2010 with Exchange Server 2003 so messages can be sent between the two Exchange versions. During setup of the first Hub Transport Server an Exchange Server 2003 Hub Server needs to be selected. This is the server the legacy Routing Group Connector will connect to:
Note that this choice can be changed and/or added to after setup is complete.
Now finish the setup wizard and install the Client Access and Hub Transport Server roles on this server.
It is also possible to use the command line setup application to setup the above mentioned configuration. Open a command prompt, navigate to the installation media and enter the following command:
Mailbox Storage Design
Before installing the Exchange Server 2010 Mailbox Server role a proper storage design has to be made. Microsoft has recently released the new storage calculator, which is now called the “Exchange 2010 Mailbox Server Role Requirements Calculator” and can be downloaded here ( Alo attached in this post):
msexchangeteam.com/archive/2009/11/09/453117.aspx.
The Requirements Calculator needs to be used for a proper storage design. The following variables are used in the Requirements Calculator for our example:
The Requirements Calculator will show the following results:
An interesting part of Exchange Server 2010 is the database technology. Microsoft has made significant changes to the database structure to lower the disk performance requirements. It should be sufficient to run the Mailbox databases and its accompanying log files from SATA disks.
In the Requirements Calculator there’s the possibility to enter the disk configuration. For the new Inframan Mailbox server 7.200 RPM SATA disks with a capacity of 500 GB will be used for storing the databases and 7.200 RPM SATA disks with a capacity of 250GB will be used for storing the log files. This disk configuration is not exactly a high end configuration, but it is by far the most cost effective solution.
The Requirements Calculator contains a tab called “Storage Design”. When using the above mentioned values the Calculator recommends a RAID1/0 configuration with 6 SATA disks for storing the Mailbox Databases and a RAID1/0 configuration with 2 SATA disks for storing the Log Files.
Installing the Mailbox Server role
When the storage solution has been properly designed and implemented the Exchange Server 2010 Mailbox Server role can be installed. As with the Client Access and Hub Transport Server roles make sure you download the Language Pack during setup. Select a ‘custom setup’ and select only the Mailbox Server role when you get to the ‘Server Role selection’ window as shown in Figure 5. Finish the setup wizard and install the Mailbox Server role. After installation of the 2nd server the organization is ready to be configured and we can prepare for start moving mailboxes from Exchange Server 2003 to Exchange Server 2010
Configuring the Exchange Server 2010 servers
When both Exchange servers are installed it is time to configure the Exchange environment properly before Exchange Server 2010 can be used and mailboxes can be moved. The following needs to be configured:
•Relocate the Mailbox Databases on the new storage solution;
•Unified Communications certificate on the Client Access Server;
•New server certificate on the Exchange 2003 front-end server;
•OWA 2010 needs to be configured for use with Exchange Server 2003;
•Public Folder replication.
•A send and receive connector also have to be configured, when the mail flow will be changed from Exchange Server 2003 to Exchange Server 2010.
Relocate the Mailbox Databases
On the new Mailbox Server there are two drives, from a hardware perspective configured as outlined before. These drives are F:\ for the Mailbox Databases and the Public Folder database and drive G:\ for the Log Files.
To change the location of the Mailbox Database open the Exchange Management Console and navigate to the Database Management, which can be found in the Organization Configuration. Right click the database and select “Move Database Path”. Change the Database file path to a directory on drive F:\ and change the Log folder path to a directory on drive G:\. Repeat this step for the Public Folder database.
If needed create new databases and locate the new database file on drive F:\ and the accompanying log files on driver G:\
Unified Communications Certificate
On the Exchange Server 2010 Client Access Server a new 3rd party Unified Communications certificate needs to be installed. According to Microsoft knowledge base article 929395 (http://support.microsoft.com/kb/929395) the following Certificate Authorities are supported for use with Unified Communications certificates:
•Entrust - www.entrust.net/microsoft/
•Digicert - www.digicert.com/unified-communications-ssl-tls.htm
•Comodo - www.comodo.com/msexchange
However, most SSL Certificate Authorities can generate UC/SAN certificates that will work just fine. New in Exchange Server 2010 is the possibility to request certificates using the Exchange Management Console. Open the Exchange Management Console and select the Server Configuration in the navigation pane. Select the Exchange Server 2010 Client Access Server and create a new certificate request. For our environment we have to use the following domain names in our certificate:
•Webmail.inframan.nl
•Autodiscover.inframan.nl
•Legacy.inframan.nl
During the coexistence phase Internet clients will connect to the Exchange Server 2010 Client Access Server while their mailbox is still on Exchange Server 2003. The client request will then be redirected to the old Exchange Server 2003 front-end server. This server will therefore get a new FQDN (Fully Qualified Domain Name) and thus need a new certificate. This new FQDN will be legacy.inframan.nl
OWA Configuration
During installation of the Exchange Server 2010 Client Access Server all settings have been configured for use on the Internet. The only thing that needs to be configured is the coexistence information for Outlook Web App. The Client Access Server needs to be configured in case a mailbox is still on Exchange Server 2003 and the client needs to be redirected to the Exchange Server 2003 front-end server.
On an Exchange Server 2010 server enter the following Management Shell Command:
This will make sure that when a user connects to Exchange Server 2010 Client Access Server for Outlook Web Access and the mailbox is still on Exchange 2003 the client will be redirected to the old Exchange Server 2003 front-end server.
Public Folder Replication
During installation of the Mailbox Server a new Exchange Server 2010 Mailbox Database will be automatically created. After installation you have to make sure that this database is moved from the default location to an alternate location for recovery and performance reasons.
A new Public Folder database will also be automatically created on the new Mailbox Server. The hierarchy, which is the structure of all Public Folders will be automatically replicated between all Public Folder Databases in the entire organization. The content replication of the Public Folders will have to be configured manually though.
To replicate the Offline Address Book and Free/Busy folders from Exchange Server 2003 to Exchange Server 2010 open the Exchange System Manager on the Exchange Server 2003 server and navigate to the System Folders in the ‘Folders’ folder in the First Administrative Group Navigate to the first Offline Address Book folder, right click it and select “All Tasks…”. The next is to select “Manage Settings”.
If you want to toggle between the System Folders and the normal Public Folders, navigate to the Public Folders, right click the Public Folders and select “View System Folders” or “View Public Folders”.
During installation of the Mailbox Server a new Exchange Server 2010 Mailbox Database will be automatically created. After installation you have to make sure that this database is moved from the default location to an alternate location for recovery and performance reasons.
A new Public Folder database will also be automatically created on the new Mailbox Server. The hierarchy, which is the structure of all Public Folders will be automatically replicated between all Public Folder Databases in the entire organization. The content replication of the Public Folders will have to be configured manually though.
To replicate the Offline Address Book and Free/Busy folders from Exchange Server 2003 to Exchange Server 2010 open the Exchange System Manager on the Exchange Server 2003 server and navigate to the System Folders in the ‘Folders’ folder in the First Administrative Group Navigate to the first Offline Address Book folder, right click it and select “All Tasks…”. The next is to select “Manage Settings”.
If you want to toggle between the System Folders and the normal Public Folders, navigate to the Public Folders, right click the Public Folders and select “View System Folders” or “View Public Folders”.
The “Manage Public Folder Settings wizard” will appear. Click Next on the Welcome page and select the “Modify lists of replica servers”. Follow the wizard and add the Exchange Server 2010 Mailbox Server role as a new replica. When finished, the folder and all its subfolders will be replicated to the Exchange Server 2010 Public Folder database. Repeat this step for the second Offline Address Book folder and the Schedule+ Free Busy folder.
Note: When the “Manage Settings” option is not available you can select “Properties” and select the replication tab to add the Exchange Server 2010 Public Folder Database.
Note: replication of public folders can take quite some time.
The (default) Public Folder that are located on the Exchange Server 2010 Mailbox Server should be replicated to the Exchange Server 2003 Mailbox Server. To accomplish this logon to the Exchange Server 2010 Mailbox Server, open the Exchange Management Console and navigate to the Tools node. Under the Tools node open the Public Folder Management Console.
Right click the Offline Address Book in the results pane, select Properties and click the Replication tab.
Add the Exchange Server 2003 Mailbox Server to the replica list, the contents will now be replicated to the Exchange Server 2003 Mailbox Server. Be aware that Public Folder replication is a low priority mechanism, so it takes some time before both Public Folder databases are in sync.
Repeat these steps for the Schedule+ Free/Busy folder
Now the actual movement of the mailboxes and the steps that are needed to decommission the Exchange 2003 servers like moving the Offline Address Book generation server and conversion of Recipient Policies and Address Books.
Offline Address Book generation
Changing the Offline Address Book generation isn’t the most difficult part of a migration. Logon to the new Exchange 2010 Server and open the Exchange Management Console. In the navigation pane, navigate to the Organization Configuration and select the Mailbox option. In the results pane, select the Offline Address Book tab. Right here you’ll see that the ‘old’ 2003 Mailbox Server is the Offline Address Book generation server. Right click this server and select ‘Move…’. The Move Offline Address Book wizard will appear, use the Browse button to select the Exchange 2010 Mailbox Server Role as the new generation server. Click the Move button to finish the wizard. When finished click the Finish button
Address List conversion
There’s no way to achieve this using the Exchange Management Console so we need the Exchange Management Shell. When you try to edit a Recipient Policy in Exchange Server 2010 Management Console it gives a clue on how to convert the Recipient Policies to E-mail Address Policies:
Besides the fact that you have to convert the Recipient Policies to Email Address Policies there’s another very important aspect. Exchange Server 2003 can use LDAP queries for Recipient Policies while Exchange Server 2007 and Exchange Server 2010 use a new technique called OPATH filtering for creating queries. The OPATH filtering syntax replaces the LDAP filtering syntax. Using OPATH it is possible to create filters directly in the Exchange Management Shell using the –RecipientFilter parameter.
LDAP filters are supported in Exchange Server 2010, and they continue to work, but they only exist on objects that are migrated from Exchange Server 2003 or earlier.But if you want to edit LDAP filters they : gallery.technet.microsoft.com/scriptcenter/7c04b866-f83d-4b34-98ec-f944811dd48d
If you don’t use any LDAP filtering in your Recipient Policies you can convert the Recipient Policies directly to Email Address Policies.
The Set-EmailAddressPolicy cmdlet is needed for this.
Open the Exchange Management Shell and enter the following command:
This will show a list of Recipient Policies that are available in your Exchange organization. We can use this output by piping it into the Set-EmailAddressPolicy cmdlet:
The Recipient Policies are now converted to Exchange Server 2010 Email Address Policies and you can open them in the Exchange Management Console. Please note that the examples mentioned above are pretty simple policies. If you have more complex policies please test this thoroughly. If you have any Mailbox Manager policies, these have to be removed.
Warning:
if you happen to do this on Recipient Policies that have (advanced) LDAP queries, all custom filters can be reset to "mailnickname=*" which can result significant email outages. You have to test all these changes in a dedicated lab environment to see how these changes will affect your Exchange environment!
The Address Lists need to be converted to Exchange Server 2010 as well. To achieve this open an Exchange Management Shell and enter the following commands:
When finished you can open all Address Lists using the Exchange Management Console and using the Exchange 2003 System Manager for opening the Address Lists is no longer possible.
Mail flow settings
Before changing the actual SMTP mailflow we have to create a Send Connector first. This will allow the Hub Transport Server to send SMTP mail to the Internet directly. In the Exchange Management Console, navigate to the Organization Configuration and select the Hub Transport Server. In the Actions Pane select “New Send Connector…” and create a new SMTP connector to the Internet. Select * in the namespace (this will send all outbound messages go through this connector) and select the DNS or the Smarthost option, depending on your own situation
By default the Receive Connector on the Exchange 2010 Hub Transport Server will not allow any anonymous connections. To change this open the Exchange Management Console, navigate to the Server Configuration and select the Hub Transport Server in the Results Pane. Right Click the default Receive Connector and select its properties. Select the Permissions tab and check the “anonymous” option to enable SMTP anonymous access.
Now that everything is in place, we can start moving the messaging services to Exchange Server 2010. Although there’s no hard requirement to start with the mail flow I’m going to start here. In the original configuration, mail from the Internet is delivered to the ISA 2006 Server and from there it is sent to the Exchange 2003 front-end server. We’ll change the ISA Server configuration so that SMTP mail is delivered to the Exchange Server 2010 Hub Transport Server. When a mailbox is still on Exchange Server 2003 the message is sent across the Interop Routing Group Connector from Exchange Server 2010 to Exchange Server 2003 where it is delivered to the intended Recipient. The Interop Routing Group Connector was created during setup of the Hub Transport Server as explained in the previous chapter. On the ISA 2006 Server open the ISA Server Management Console and navigate to the Firewall Policy. In the results pane select the SMTP rule and edit it so SMTP messages are delivered to the new Exchange 2010 Hub Transport Server.
Outbound SMTP traffic needs to be changed as well. In the original situation there was an SMTP connector from the Exchange Server 2003 Front-End Server towards the Internet. A new Send Connector on the Exchange Server 2010 Hub Transport Server needs to be created that will replace the old Exchange Server 2003 SMTP Connector.
Log on to the Exchange Server 2010 Hub Transport Server and open the Exchange Management Console. Navigate to the Organization Configuration and select the Hub Transport. In the Results Pane select the Send Connectors tab and select “New Send Connector” in the Actions Pane and follow the wizard to create a new Send Connector. In the Address Space windows select “*” as the address space to make sure all messages are routed through this connector. In the Network Settings window you have to select either to use DNS (the Hub Transport Server will send all messages to other hosts) or to use a smart host (the Hub Transport Server will forward all messages to this host which in turn will send it to all other hosts).
If the new Send Connector is working, the SMTP Connector on the Exchange Server 2003 Front-End Server can be removed. If removed, messages from Exchange Server 2003 mailboxes bound to the Internet go through the Interop Routing Group Connector to the Exchange Server 2010 Hub Transport Server and then through the Send Connector to the Internet.
Client Access Server
In the previous article regarding the upgrade from Exchange Server 2003 to Exchange Server 2010 I explained the different namespaces. On the Exchange Server 2010 Client Access Server there’s a certificate with the following names:
•Webmail.inframan.nl
•Autodiscover.inframan.nl
•Legacy.inframan.nl
When an OWA client logs on to the Exchange Server 2010 Client Access Server and the particular mailbox is still on Exchange Server 2003 the client gets redirected to the Exchange Server 2003 front-end server. This server will have the legacy. Inframan.nl name, since two servers cannot have the same Fully Qualified Domain Name (webmail.inframan.nl).
The new certificate on the Exchange Server 2010 Client Access Server can be exported and imported on the Exchange Server 2003 Front-End Server. This way an error message will not be shown when a client gets redirected to the Exchange Server 2003 Front-End Server.
Note. The certificate needs to be imported on the ISA 2006 Server as well.
After importing the new certificate on the Exchange Server 2003 Front-End server and the ISA 2006 Server the clients continue working, but with the new certificate, so you’ll face only a small downtime (one minute) here when replacing the certificate.
Changing the ISA 2006 Server rules takes a bit more planning. Three new rules will be created:
•Exchange 2010 OWA rule;
•Exchange 2010 ActiveSync rule;
•Exchange 2010 Outlook Anywhere and Autodiscover rule;
Do not Apply the changes to the ISA Server at this moment, but uncheck the ‘enable’ option on each rule to prevent immediate activation.
For the ‘old’ Exchange 2003 legacy environment three rules have to be created on the ISA 2006 Server as well:
•Exchange 2003 OWA rule;
•Exchange 2003 ActiveSync rule;
•Exchange 2003 RPC over HTTP rule (this one can be combined with the previous rule however);
As with the Exchange 2010 do not apply these rules immediately, but uncheck the ‘enable’ option on every rule before applying these changes.
The Web Listener in ISA 2006 Server needs to be changed as well. Since a seamless experience for end-users is needed when the redirection occurs, the Single Sign-On option need to be enabled on the Web Listener.
In the ISA Server Management Console open the properties of the Web Listener and navigate to the SSO tab. Add the .inframan.nl in the SSO domain, please note the leading dot.
When you have configured the above options it’s time to apply all changes in the ISA Server. Enable the 2010 firewall rules, enable the legacy Exchange 2003 rules and disable the old Exchange 2003 rules. All clients are now connected to the Exchange Server 2010 Client Access Server and when needed the clients are redirected to the Exchange Server 2003 Front-End Server.
In the ISA Server Management Console open the properties of the Web Listener and navigate to the SSO tab. Add the .inframan.nl in the SSO domain, please note the leading dot.
When you have configured the above options it’s time to apply all changes in the ISA Server. Enable the 2010 firewall rules, enable the legacy Exchange 2003 rules and disable the old Exchange 2003 rules. All clients are now connected to the Exchange Server 2010 Client Access Server and when needed the clients are redirected to the Exchange Server 2003 Front-End Server.
Move Mailboxes ... continued below
Exchange 2010 contains a lot of compelling new features such as the new High Availability, the facility to store your Exchange databases on JBOD (Just a Bunch of Disks), the archiving option and the new Outlook Web App and do not forget the new Windows Mobile 6.5 and its new mail client.
If you have an Exchange Server 2003 environment you may want to skip Exchange Server 2007 and move directly to Exchange Server 2010. The easiest way to achieve this is to integrate Exchange Server 2010 into the existing Exchange Server 2003 environment, a so called intra-organizational migration. This is also known as transitioning from Exchange Server 2003 to Exchange Server 2010.
Exchange Server 2003
Suppose we have a fictitious company called Inframan, which is a consulting company specializing in bridges, tunnels, buildings etc. Inframan has approximately 500 employees, 50 employees are working in the office, 450 employees are working ‘in the field’. Employees within the office have their own desktop which connects to an Exchange 2003 Mailbox Server using Outlook 2003 and Outlook 2007. Employees outside the office connect to the office using their company laptop with Outlook and with Windows Mobile devices. When needed they can use their PC at home to use Outlook Web Access to access their mailbox. Typical usage profile is “light”, approximately 25 messages are received per day and 10 messages are sent per day, per user that is. Behind the firewall is an ISA Server 2006 acting as a reverse proxy to publish all Exchange Services to the Internet. Inframan’s environment will look something like this:
Inframan is using only one namespace for accessing all services from the Internet: webmail.inframan.nl. This is used for Outlook Web Access, Outlook Anywhere(RPC over HTTP) and Windows Mobile devices.
Recently Inframan has been thinking about upgrading to Exchange Server 2007, but they decided to move directly to Exchange Server 2010.
Coexistence with Exchange Server 2010
Exchange Server 2010 can easily coexist in a Exchange Server 2003 organization as long as the Exchange Server 2010 prerequisites are met:
•The Active Directory forest needs to be in Windows Server 2003 forest functionality mode;
•All domains that contain Exchange recipients need to be in Windows Server 2003 domain native mode;
•The Global Catalog Servers and the Active Directory Schema Master need to be at a minimum level of Windows Server 2003 SP1 (which equals to Windows Server 2003 R2);
•The Exchange 2003 organization needs to be running in ‘native mode’;
•Link State updates on all Exchange Server 2003 servers need to be disabled according to Microsoft knowledge base article 'Suppress Link State Updates'
Suppress Link State Updates
2 out of 2 rated this helpful - Rate this topic
Applies to: Exchange Server 2010 SP2
Topic Last Modified: 2011-04-28
This topic explains how to use Registry Editor to suppress propagation of minor link state updates between routing groups in Microsoft Exchange Server 2010 and Exchange Server 2003.
We recommend that you perform this procedure if the following conditions are true:
You have installed the Exchange 2010 Hub Transport server role in an existing Exchange 2003 organization. For more information about this step, see Install Exchange 2010 in an Existing Exchange 2003 Organization.
The existing Exchange organization includes more than one Exchange 2003 routing group.
You will configure more than one routing group connector between Exchange 2003 routing groups and Exchange 2010.
The first routing group connector is created when the first Hub Transport server role is installed on a computer in the Exchange organization. Before you create additional routing group connectors, perform this procedure on every Exchange 2003 server in the organization. When you suppress minor link state updates, the servers running Exchange 2003 don't mark connectors as unavailable. This procedure makes sure that earlier versions of Exchange only use least cost routing and don't try to calculate an alternative route.
The purpose of this procedure is to make sure that routing loops can't occur. Exchange 2010 doesn't use a link state routing table and doesn't support relay of link state information. If you don't suppress minor link state updates, routing loops may occur. For more information about how routing occurs in an Exchange organization that includes Exchange 2010 servers and Exchange 2003 servers, see Upgrade from Exchange 2003 Transport.
Caution:
Incorrectly editing the registry can cause serious problems that may require you to reinstall your operating system. Problems resulting from editing the registry incorrectly may not be able to be resolved. Before editing the registry, back up any valuable data.
Suppress Link State Updates on Exchange 2003
--------------------------------------------------------------------------------
To perform this procedure, you must log on to the Exchange 2003 server by using an account that is delegated membership in the local Administrators group.
1.Open Registry Editor.
2.Locate HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\RESvc\Parameters.
3.Right-click Parameters and select New | DWORD value. Name the new DWORD value SuppressStateChanges.
4.Double-click SuppressStateChanges.
5.In the Value data field, enter 1.
6.Close Registry Editor, and then restart the SMTP service, the Microsoft Exchange Routing Engine service, and the Microsoft Exchange MTA Stacks services for the change to take effect.
Inframan will build two new Exchange Server 2010 servers, one combined Hub Transport Server / Client Access Server and one dedicated Mailbox Server. These Servers will be installed in the same Windows Server 2003 Active Directory domain as the Exchange Server 2003 organization. This will greatly improve the ease of moving mailbox from Exchange Server 2003 to Exchange Server 2010.
Moving from Exchange Server 2003 to Exchange Server 2010 in the same Active Directory forest is called transitioning. Building a new Active Directory forest with a new Exchange Server 2010 organization and moving mailboxes from the old Active Directory to the new Active Directory is called migrating.
The interim messaging environment, where both Exchange Server 2003 and Exchange Server 2010 coexist in the same Active Directory domain will look like this:
In Exchange Server 2007 Internet clients could connect to the Exchange Server 2007 Client Access Server while the mailbox was still on Exchange Server 2003. The Client Access Server retrieves the data out of the mailbox and sends it back to the Internet client. In Exchange Server 2010 this has changed. When a client connects to Exchange Server 2010, it actually connects to the Exchange Server 2010 Client Access Server and if the mailbox is still on the Exchange Server 2003 Mailbox Server then the client is redirected to the Exchange Server 2003 front-end server. This front-end server then handles the connection request. This automatically means the namespaces of the Exchange environment will change. For Inframan this means that the following namespaces are used:
•https://webmail.inframan.nl – This is used by all Internet clients that connect to the Exchange environment. This name is not different than in the Exchange Server 2003 namespace, but it will now point to the Exchange Server 2010 Client Access Server;
•https://autodiscover.inframan.nl – This is used by Outlook 2007 and (Outlook 2010) clients for autodiscover purposes;
•legacy.inframan.nl – This will be the new namespace for the Exchange Server 2003 front-end server. This automatically means that the namespace for the Exchange Server 2003 front-end server is going to change!
The servers that will hold the Exchange Server 2010 server roles have the following prerequisites:
•The servers need to be running on Windows Server 2008 or Windows Server 2008 R2;
•.Net framework 3.5 with SP1 needs to be installed;
•PowerShell 2.0 needs to be installed;
•Office 2007 Filter packs needs to be installed for the Hub Transport Server role and the Mailbox Server role;
Make sure that after installing Windows on the servers that they are up-to-date with the latest hotfixes and service packs.
The first step for Exchange Server 2010 Server is to upgrade the Active Directory schema to contain the Exchange Server 2010 extensions. This is achieved by using the Exchange Server 2010 setup application followed by a number of parameter:
Setup.com /PrepareLegacyExchangePermissions – Exchange Server 2003 uses the Recipient Update Service to stamp the user with the appropriate Exchange attributes during provisioning. This is replaced in Exchange Server 2010 by E-Mail Address Policies. The /PrepareLegacyExchangePermissions parameter changes security settings so that both the Recipient Update Service and E-mail Address Policies can coexist in the same Active Directory;
Setup.com /PrepareSchema – This command upgrades the Active Directory schema to include the Exchange Server 2010 extensions. This can be checked by using ADSIEDit and checking the value of the UpperRange parameter of the CN=ms-Exch-Schema-Version-Pt object in the Schema. This should have one of the following values:
Note that the value is the same in Exchange Server 2007 service pack 2 and in Exchange Server 2010 RTM – this is because Exchange Server 2007 service pack 2 will install the Exchange Server 2010 schema extensions.
Setup.com /PrepareAD – This command upgrades the Exchange organization, which is stored in the configuration partition in Active Directory to support Exchange Server 2010. In Exchange Server 2003 information is stored in the “First Administrative Group” or perhaps more if you created additional Administrative Groups. The Exchange Server 2010 setup application will create a new Administrative Group called “Exchange Administrative Group (FYDIBOHF23SPDLT)” where all Exchange Server 2010 configuration information is stored. This will be visible in the Exchange Server 2003 System Manager:
Setup.com /PrepareDomain – This is the last step in preparing the Active Directory and will create all necessary groups in the domain being prepared.
When Active Directory is fully prepared we can continue with installing the first Exchange Server 2010 server in the environment. For our example, this has to be the combined Hub Transport and Client Access Server. Start the graphical setup program (setup.exe) and download the Language File bundle if needed. If you select “install only languages from the DVD” only the language setting of your DVD (for example English or French) will be available. This is used not only for the language of the Exchange Server, but also the available language settings for the clients being used.
During the installation of the combined Hub Transport and Client Access Server a so called ‘custom setup’ will be used. This means we can select which server roles will be installed. In the Inframan example the following needs to be selected during setup:
When continuing the setup application a window will be shown asking if this Client Access Server is Internet facing and if so, what the external domain will be. This is an important step because it configures the Client Access Server automatically with the appropriate settings. Check the “The Client Access server will be Internet-facing” option and enter the external domain name. This is “webmail.inframan.nl” in our example
Exchange Server 2003 uses Routing Groups to determine the proper way to route messages while Exchange Server 2010 uses Active Directory sites for routing. These are not compatible with each other so a legacy Routing Group Connector will be created within Exchange Server 2010. This legacy connector connects Exchange Server 2010 with Exchange Server 2003 so messages can be sent between the two Exchange versions. During setup of the first Hub Transport Server an Exchange Server 2003 Hub Server needs to be selected. This is the server the legacy Routing Group Connector will connect to:
Note that this choice can be changed and/or added to after setup is complete.
Now finish the setup wizard and install the Client Access and Hub Transport Server roles on this server.
It is also possible to use the command line setup application to setup the above mentioned configuration. Open a command prompt, navigate to the installation media and enter the following command:
Setup.com /mode:install /roles:ht,ca,mt /ExternalCASServerDomain:
webmail.inframan.nl /LegacyRoutingServer:2003FE.inframan.local
webmail.inframan.nl /LegacyRoutingServer:2003FE.inframan.local
Mailbox Storage Design
Before installing the Exchange Server 2010 Mailbox Server role a proper storage design has to be made. Microsoft has recently released the new storage calculator, which is now called the “Exchange 2010 Mailbox Server Role Requirements Calculator” and can be downloaded here ( Alo attached in this post):
msexchangeteam.com/archive/2009/11/09/453117.aspx.
The Requirements Calculator needs to be used for a proper storage design. The following variables are used in the Requirements Calculator for our example:
The Requirements Calculator will show the following results:
An interesting part of Exchange Server 2010 is the database technology. Microsoft has made significant changes to the database structure to lower the disk performance requirements. It should be sufficient to run the Mailbox databases and its accompanying log files from SATA disks.
In the Requirements Calculator there’s the possibility to enter the disk configuration. For the new Inframan Mailbox server 7.200 RPM SATA disks with a capacity of 500 GB will be used for storing the databases and 7.200 RPM SATA disks with a capacity of 250GB will be used for storing the log files. This disk configuration is not exactly a high end configuration, but it is by far the most cost effective solution.
The Requirements Calculator contains a tab called “Storage Design”. When using the above mentioned values the Calculator recommends a RAID1/0 configuration with 6 SATA disks for storing the Mailbox Databases and a RAID1/0 configuration with 2 SATA disks for storing the Log Files.
Installing the Mailbox Server role
When the storage solution has been properly designed and implemented the Exchange Server 2010 Mailbox Server role can be installed. As with the Client Access and Hub Transport Server roles make sure you download the Language Pack during setup. Select a ‘custom setup’ and select only the Mailbox Server role when you get to the ‘Server Role selection’ window as shown in Figure 5. Finish the setup wizard and install the Mailbox Server role. After installation of the 2nd server the organization is ready to be configured and we can prepare for start moving mailboxes from Exchange Server 2003 to Exchange Server 2010
Configuring the Exchange Server 2010 servers
When both Exchange servers are installed it is time to configure the Exchange environment properly before Exchange Server 2010 can be used and mailboxes can be moved. The following needs to be configured:
•Relocate the Mailbox Databases on the new storage solution;
•Unified Communications certificate on the Client Access Server;
•New server certificate on the Exchange 2003 front-end server;
•OWA 2010 needs to be configured for use with Exchange Server 2003;
•Public Folder replication.
•A send and receive connector also have to be configured, when the mail flow will be changed from Exchange Server 2003 to Exchange Server 2010.
Relocate the Mailbox Databases
On the new Mailbox Server there are two drives, from a hardware perspective configured as outlined before. These drives are F:\ for the Mailbox Databases and the Public Folder database and drive G:\ for the Log Files.
To change the location of the Mailbox Database open the Exchange Management Console and navigate to the Database Management, which can be found in the Organization Configuration. Right click the database and select “Move Database Path”. Change the Database file path to a directory on drive F:\ and change the Log folder path to a directory on drive G:\. Repeat this step for the Public Folder database.
If needed create new databases and locate the new database file on drive F:\ and the accompanying log files on driver G:\
Unified Communications Certificate
On the Exchange Server 2010 Client Access Server a new 3rd party Unified Communications certificate needs to be installed. According to Microsoft knowledge base article 929395 (http://support.microsoft.com/kb/929395) the following Certificate Authorities are supported for use with Unified Communications certificates:
•Entrust - www.entrust.net/microsoft/
•Digicert - www.digicert.com/unified-communications-ssl-tls.htm
•Comodo - www.comodo.com/msexchange
However, most SSL Certificate Authorities can generate UC/SAN certificates that will work just fine. New in Exchange Server 2010 is the possibility to request certificates using the Exchange Management Console. Open the Exchange Management Console and select the Server Configuration in the navigation pane. Select the Exchange Server 2010 Client Access Server and create a new certificate request. For our environment we have to use the following domain names in our certificate:
•Webmail.inframan.nl
•Autodiscover.inframan.nl
•Legacy.inframan.nl
During the coexistence phase Internet clients will connect to the Exchange Server 2010 Client Access Server while their mailbox is still on Exchange Server 2003. The client request will then be redirected to the old Exchange Server 2003 front-end server. This server will therefore get a new FQDN (Fully Qualified Domain Name) and thus need a new certificate. This new FQDN will be legacy.inframan.nl
OWA Configuration
During installation of the Exchange Server 2010 Client Access Server all settings have been configured for use on the Internet. The only thing that needs to be configured is the coexistence information for Outlook Web App. The Client Access Server needs to be configured in case a mailbox is still on Exchange Server 2003 and the client needs to be redirected to the Exchange Server 2003 front-end server.
On an Exchange Server 2010 server enter the following Management Shell Command:
Set-OWAVirtualDirectory <CASHUB01>\OWA ‘
-ExternalURL webmail.inframan.nl/OWA ‘
-Exchange2003URL legacy.inframan.nl/exchange
-ExternalURL webmail.inframan.nl/OWA ‘
-Exchange2003URL legacy.inframan.nl/exchange
This will make sure that when a user connects to Exchange Server 2010 Client Access Server for Outlook Web Access and the mailbox is still on Exchange 2003 the client will be redirected to the old Exchange Server 2003 front-end server.
Public Folder Replication
During installation of the Mailbox Server a new Exchange Server 2010 Mailbox Database will be automatically created. After installation you have to make sure that this database is moved from the default location to an alternate location for recovery and performance reasons.
A new Public Folder database will also be automatically created on the new Mailbox Server. The hierarchy, which is the structure of all Public Folders will be automatically replicated between all Public Folder Databases in the entire organization. The content replication of the Public Folders will have to be configured manually though.
To replicate the Offline Address Book and Free/Busy folders from Exchange Server 2003 to Exchange Server 2010 open the Exchange System Manager on the Exchange Server 2003 server and navigate to the System Folders in the ‘Folders’ folder in the First Administrative Group Navigate to the first Offline Address Book folder, right click it and select “All Tasks…”. The next is to select “Manage Settings”.
If you want to toggle between the System Folders and the normal Public Folders, navigate to the Public Folders, right click the Public Folders and select “View System Folders” or “View Public Folders”.
During installation of the Mailbox Server a new Exchange Server 2010 Mailbox Database will be automatically created. After installation you have to make sure that this database is moved from the default location to an alternate location for recovery and performance reasons.
A new Public Folder database will also be automatically created on the new Mailbox Server. The hierarchy, which is the structure of all Public Folders will be automatically replicated between all Public Folder Databases in the entire organization. The content replication of the Public Folders will have to be configured manually though.
To replicate the Offline Address Book and Free/Busy folders from Exchange Server 2003 to Exchange Server 2010 open the Exchange System Manager on the Exchange Server 2003 server and navigate to the System Folders in the ‘Folders’ folder in the First Administrative Group Navigate to the first Offline Address Book folder, right click it and select “All Tasks…”. The next is to select “Manage Settings”.
If you want to toggle between the System Folders and the normal Public Folders, navigate to the Public Folders, right click the Public Folders and select “View System Folders” or “View Public Folders”.
The “Manage Public Folder Settings wizard” will appear. Click Next on the Welcome page and select the “Modify lists of replica servers”. Follow the wizard and add the Exchange Server 2010 Mailbox Server role as a new replica. When finished, the folder and all its subfolders will be replicated to the Exchange Server 2010 Public Folder database. Repeat this step for the second Offline Address Book folder and the Schedule+ Free Busy folder.
Note: When the “Manage Settings” option is not available you can select “Properties” and select the replication tab to add the Exchange Server 2010 Public Folder Database.
Note: replication of public folders can take quite some time.
The (default) Public Folder that are located on the Exchange Server 2010 Mailbox Server should be replicated to the Exchange Server 2003 Mailbox Server. To accomplish this logon to the Exchange Server 2010 Mailbox Server, open the Exchange Management Console and navigate to the Tools node. Under the Tools node open the Public Folder Management Console.
Right click the Offline Address Book in the results pane, select Properties and click the Replication tab.
Add the Exchange Server 2003 Mailbox Server to the replica list, the contents will now be replicated to the Exchange Server 2003 Mailbox Server. Be aware that Public Folder replication is a low priority mechanism, so it takes some time before both Public Folder databases are in sync.
Repeat these steps for the Schedule+ Free/Busy folder
Now the actual movement of the mailboxes and the steps that are needed to decommission the Exchange 2003 servers like moving the Offline Address Book generation server and conversion of Recipient Policies and Address Books.
Offline Address Book generation
Changing the Offline Address Book generation isn’t the most difficult part of a migration. Logon to the new Exchange 2010 Server and open the Exchange Management Console. In the navigation pane, navigate to the Organization Configuration and select the Mailbox option. In the results pane, select the Offline Address Book tab. Right here you’ll see that the ‘old’ 2003 Mailbox Server is the Offline Address Book generation server. Right click this server and select ‘Move…’. The Move Offline Address Book wizard will appear, use the Browse button to select the Exchange 2010 Mailbox Server Role as the new generation server. Click the Move button to finish the wizard. When finished click the Finish button
Address List conversion
There’s no way to achieve this using the Exchange Management Console so we need the Exchange Management Shell. When you try to edit a Recipient Policy in Exchange Server 2010 Management Console it gives a clue on how to convert the Recipient Policies to E-mail Address Policies:
Besides the fact that you have to convert the Recipient Policies to Email Address Policies there’s another very important aspect. Exchange Server 2003 can use LDAP queries for Recipient Policies while Exchange Server 2007 and Exchange Server 2010 use a new technique called OPATH filtering for creating queries. The OPATH filtering syntax replaces the LDAP filtering syntax. Using OPATH it is possible to create filters directly in the Exchange Management Shell using the –RecipientFilter parameter.
LDAP filters are supported in Exchange Server 2010, and they continue to work, but they only exist on objects that are migrated from Exchange Server 2003 or earlier.But if you want to edit LDAP filters they : gallery.technet.microsoft.com/scriptcenter/7c04b866-f83d-4b34-98ec-f944811dd48d
# Powershell script to convert LDAP filter (purportedSearch) to OPATH filter
#
#################################################################################
#
# This script is not officially supported by Microsoft, use it at your own risk.
# Microsoft has no liability, obligations, warranty, or responsibility regarding
# any result produced by use of this file.
#
#################################################################################
#
# Examples on ways to use this script in Powershell...
#
# To convert a manually entered filter and display the result:
#
# .\ConvertFrom-LdapFilter "(&(mailnickname=*))"
#
# To convert the LDAP filter on an existing address list and display the result:
#
# .\ConvertFrom-LdapFilter (Get-AddressList "My Address List").LdapRecipientFilter
#
# To convert the LDAP filter on an existing address list and update the address list with the new filter:
#
# Set-AddressList "My Address List" -RecipientFilter ( .\ConvertFrom-LdapFilter (Get-AddressList "My Address List").LdapRecipientFilter )
#
# To convert all existing legacy address lists and display the result without actually updating them:
#
# Get-AddressList | WHERE { $_.RecipientFilterType -eq 'Legacy' } | foreach { .\ConvertFrom-LdapFilter $_.LdapRecipientFilter }
#
# To convert all existing legacy address lists and output the name, current LDAP filter, and the generated OPATH to a tab-delimited file without actually updating the address lists:
#
# Get-AddressList | WHERE { $_.RecipientFilterType -eq 'Legacy' } | foreach { $_.Name + [char]9 + $_.LdapRecipientFilter + [char]9 + (.\ConvertFrom-LdapFilter $_.LdapRecipientFilter) } > C:\suggestedfilters.txt
#
# To convert all existing legacy address lists and actually update the address lists without prompting:
#
# Get-AddressList | WHERE { $_.RecipientFilterType -eq 'Legacy' } | foreach { Set-AddressList $_.Name -RecipientFilter (.\ConvertFrom-LdapFilter $_.LdapRecipientFilter) -ForceUpgrade }
#
# To convert all legacy address lists, GALs, and email address policies, without prompting, run three commands:
#
# Get-AddressList | WHERE { $_.RecipientFilterType -eq 'Legacy' } | foreach { Set-AddressList $_.Name -RecipientFilter (.\ConvertFrom-LdapFilter $_.LdapRecipientFilter) -ForceUpgrade }
# Get-GlobalAddressList | WHERE { $_.RecipientFilterType -eq 'Legacy' } | foreach { Set-GlobalAddressList $_.Name -RecipientFilter (.\ConvertFrom-LdapFilter $_.LdapRecipientFilter) -ForceUpgrade }
# Get-EmailAddressPolicy | WHERE { $_.RecipientFilterType -eq 'Legacy' } | foreach { Set-EmailAddressPolicy $_.Name -RecipientFilter (.\ConvertFrom-LdapFilter $_.LdapRecipientFilter) -ForceUpgrade }
#
trap
{
write-host $_.Exception.Message -fore Red
continue
}
function convert-filter
{
$output = BuildFilterFromString
return $output
}
function BuildFilterFromString
{
$script:filterString = $script:filterString.Trim()
[string[]]$conditions = GetConditionsFromString
if ($conditions.Length -gt 1)
{
throw "Invalid filter string."
}
return $conditions
}
function GetConditionsFromString
{
$script:filterString = $script:filterString.Trim()
$exitThisLevel = $false;
while (!($exitThisLevel))
{
# Special cases for default filters
# This is so that we match the ones given on the msexchangeteam.com blog
if ($script:filterString.StartsWith("(&(objectClass=user)(objectCategory=person)(mailNickname=*)(msExchHomeServerName=*))"))
{ # All Users
$script:filterString = $script:filterString.Remove(0, 83).Trim()
return "RecipientType -eq 'UserMailbox'"
}
if ($script:filterString.StartsWith("(& (mailnickname=*) (| (objectCategory=group) ))"))
{ # All Groups
$script:filterString = $script:filterString.Remove(0, 47).Trim()
return "( RecipientType -eq 'MailUniversalDistributionGroup' -or RecipientType -eq 'MailUniversalSecurityGroup' -or RecipientType -eq 'MailNonUniversalGroup' -or RecipientType -eq 'DynamicDistributionGroup' )"
}
if ($script:filterString.StartsWith("(& (mailnickname=*) (| (&(objectCategory=person)(objectClass=contact)) ))"))
{ # All Contacts
$script:filterString = $script:filterString.Remove(0, 72).Trim()
return "RecipientType -eq 'MailContact'"
}
if ($script:filterString.StartsWith("(& (mailnickname=*) (| (objectCategory=publicFolder) ))"))
{ # Public Folders
$script:filterString = $script:filterString.Remove(0, 54).Trim()
return "RecipientType -eq 'PublicFolder'"
}
if ($script:filterString.StartsWith("(& (mailnickname=*) (| (&(objectCategory=person)(objectClass=user)(!(homeMDB=*))(!(msExchHomeServerName=*)))(&(objectCategory=person)(objectClass=user)(|(homeMDB=*)(msExchHomeServerName=*)))(&(objectCategory=person)(objectClass=contact))(objectCategory=group)(objectCategory=publicFolder)(objectCategory=msExchDynamicDistributionList) ))"))
{ # Default Global Address List
$script:filterString = $script:filterString.Remove(0, 336).Trim()
return "( Alias -ne `$null -and (ObjectClass -eq 'user' -or ObjectClass -eq 'contact' -or ObjectClass -eq 'msExchSystemMailbox' -or ObjectClass -eq 'msExchDynamicDistributionList' -or ObjectClass -eq 'group' -or ObjectClass -eq 'publicFolder') )"
}
# End of default filter cases
if ($script:filterString.StartsWith("("))
{
$script:filterString = $script:filterString.Remove(0, 1).Trim()
}
else
{
throw "Invalid filter string."
}
if ($script:filterString.StartsWith("("))
{
GetConditionsFromString
}
else
{
$isNegative = $script:filterString.StartsWith("!")
$mustBeValueComparison = $false
if ($isNegative)
{
$script:filterString = $script:filterString.Remove(0, 1).Trim()
if ($script:filterString.StartsWith("("))
{
$script:filterString = $script:filterString.Remove(0, 1).Trim()
}
else
{
$mustBeValueComparison = $true
}
}
$op = ""
if ($script:filterString.StartsWith("|(homeMDB=*)(msExchHomeServerName=*))"))
{
$script:filterString = $script:filterString.Remove(0, 36)
$newCondition = " ( recipientType -eq 'UserMailbox' )"
if ($isNegative)
{
$newCondition = " -not (" + $newCondition + " )"
}
$newCondition
}
elseif ($script:filterString.StartsWith("&") -or $script:filterString.StartsWith("|"))
{
if ($mustBeValueComparison)
{
throw "Invalid filter string."
}
if ($script:filterString.StartsWith("&"))
{
$op = "and"
}
else
{
$op = "or"
}
$script:filterString = $script:filterString.Remove(0, 1).Trim()
if ($script:filterString.StartsWith("("))
{
[string[]]$theseConditions = GetConditionsFromString
$newCondition = ""
for ([int]$x = 0; $x -lt $theseConditions.Length; $x++)
{
$newCondition = $newCondition + $theseConditions[$x]
if (($x + 1) -lt $theseConditions.Count)
{
$newCondition = $newCondition + " -" + $op
}
}
if ($isNegative)
{
$newCondition = " -not (" + $newCondition + " )"
}
elseif ($theseConditions.Length -gt 1)
{
$newCondition = " (" + $newCondition + " )"
}
}
else
{
$newCondition = GetValueComparison
}
$newCondition
}
else # this better be a value comparison
{
GetValueComparison
}
if ($isNegative -and -not $mustBeValueComparison)
{
if ($script:filterString.StartsWith(")"))
{
$script:filterString = $script:filterString.Remove(0, 1).Trim()
}
else
{
throw "Invalid filter string."
}
}
if ($script:filterString.StartsWith(")"))
{
$script:filterString = $script:filterString.Remove(0, 1).Trim()
}
else
{
throw "Invalid filter string."
}
}
if (($script:filterString.StartsWith(")")) -or ($script:filterString.Length -eq 0))
{
$exitThisLevel = $true
}
}
return
}
function GetValueComparison
{
$operatorPos = $script:filterString.IndexOf("=")
$valuePos = $operatorPos + 1
if (($script:filterString[$operatorPos - 1] -eq '<') -or
($script:filterString[$operatorPos - 1] -eq '>'))
{
$operatorPos--
}
if ($operatorPos -lt 1)
{
throw "Invalid filter string."
}
$property = $script:filterString.Substring(0, $operatorPos).Trim()
$opstring = $script:filterString.Substring($operatorPos, $valuePos - $operatorPos)
$startPos = 0
# DN-valued attribute may contain parenthesis. Need to look for the end
# of the DN.
if ($property.ToLower() -eq "homemdb")
{
if (!($script:filterString[$valuePos] -eq '*'))
{
$startPos = $script:filterString.IndexOf(",DC=")
}
}
$endPos = $script:filterString.IndexOf(")", $startPos)
if ($endPos -lt 0)
{
throw "Invalid filter string."
}
$val = $script:filterString.Substring($valuePos, $endPos - $valuePos)
$script:filterString = $script:filterString.Substring($endPos)
[string]$compType = ""
if ($opstring -eq "=")
{
if ($val -eq "*")
{
$compType = "exists"
}
else
{
if ($val.IndexOf("*") -gt -1)
{
$compType = "like"
}
else
{
$compType = "equals"
}
}
}
elseif ($opstring -eq "<=")
{
$compType = "lessthanorequals"
}
elseif ($opstring -eq ">=")
{
$compType = "greaterthanorequals"
}
else
{
throw "Invalid filter string."
}
[string]$opathProp = GetOpathPropFromLdapProp $property
[string]$opathVal = GetOpathValFromLdapVal $opathProp $val
[string]$opathComparison = GetOpathComparisonFromLdapComparison $opathProp $compType $opathVal
$newCondition = " ( " + $opathProp + $opathComparison + " )"
if ($isNegative)
{
$newCondition = " -not " + $newCondition
}
$newCondition
}
function GetOpathComparisonFromLdapComparison([string]$opathProp, [string]$ldapComparison, [string]$opathVal)
{
if ($opathProp -eq "ObjectCategory" -and $ldapComparison -eq "equals")
{
return " -like '" + $opathVal + "'"
}
else
{
[string]$opathComparison = ""
if ($ldapComparison -eq "equals") { $opathComparison = " -eq '" }
elseif ($ldapComparison -eq "like") { $opathComparison = " -like '" }
elseif ($ldapComparison -eq "lessthanorequals") { $opathComparison = " -le '" }
elseif ($ldapComparison -eq "greaterthanorequals") { $opathComparison = " -ge '" }
elseif ($ldapComparison -eq "exists") { $opathComparison = " -ne `$null" }
else { throw "Could not convert unknown comparison type to OPATH comparison." }
if ($ldapComparison -ne "exists")
{
$opathComparison = $opathComparison + $opathVal + "'"
}
return $opathComparison
}
}
function GetOpathValFromLdapVal([string]$opathProp, [string]$ldapVal)
{
if ($opathProp -like "*Enabled")
{
$newBool = [System.Convert]::ToBoolean($ldapVal)
return "$" + $newBool.ToString().ToLower()
}
else
{
return $ldapVal
}
}
function GetOpathPropFromLdapProp([string]$ldapProp)
{
$ldapProp = $ldapProp.ToLower()
if ($ldapProp -eq "altrecipient") { return "ForwardingAddress" }
elseif ($ldapProp -eq "authorig") { return "AcceptMessagesOnlyFrom" }
elseif ($ldapProp -eq "c") { return "CountryOrRegion" }
elseif ($ldapProp -eq "canonicalname") { return "RawCanonicalName" }
elseif ($ldapProp -eq "cn") { return "CommonName" }
elseif ($ldapProp -eq "co") { return "Co" }
elseif ($ldapProp -eq "company") { return "Company" }
elseif ($ldapProp -eq "countrycode") { return "CountryCode" }
elseif ($ldapProp -eq "deleteditemflags") { return "DeletedItemFlags" }
elseif ($ldapProp -eq "deliveredirect") { return "DeliverToMailboxAndForward" }
elseif ($ldapProp -eq "delivcontlength") { return "MaxReceiveSize" }
elseif ($ldapProp -eq "department") { return "Department" }
elseif ($ldapProp -eq "description") { return "Description" }
elseif ($ldapProp -eq "directreports") { return "DirectReports" }
elseif ($ldapProp -eq "displayname") { return "DisplayName" }
elseif ($ldapProp -eq "displaynameprintable") { return "SimpleDisplayName" }
elseif ($ldapProp -eq "distinguisedname") { return "Id" }
elseif ($ldapProp -eq "dlmemrejectperms") { return "RejectMessagesFromDLMembers" }
elseif ($ldapProp -eq "dlmemsubmitperms") { return "AcceptMessagesOnlyFromDLMembers" }
elseif ($ldapProp -eq "extensionattribute1") { return "customAttribute1" }
elseif ($ldapProp -eq "extensionattribute2") { return "customAttribute2" }
elseif ($ldapProp -eq "extensionattribute3") { return "customAttribute3" }
elseif ($ldapProp -eq "extensionattribute4") { return "customAttribute4" }
elseif ($ldapProp -eq "extensionattribute5") { return "customAttribute5" }
elseif ($ldapProp -eq "extensionattribute6") { return "customAttribute6" }
elseif ($ldapProp -eq "extensionattribute7") { return "customAttribute7" }
elseif ($ldapProp -eq "extensionattribute8") { return "customAttribute8" }
elseif ($ldapProp -eq "extensionattribute9") { return "customAttribute9" }
elseif ($ldapProp -eq "extensionattribute10") { return "customAttribute10" }
elseif ($ldapProp -eq "extensionattribute11") { return "customAttribute11" }
elseif ($ldapProp -eq "extensionattribute12") { return "customAttribute12" }
elseif ($ldapProp -eq "extensionattribute13") { return "customAttribute13" }
elseif ($ldapProp -eq "extensionattribute14") { return "customAttribute14" }
elseif ($ldapProp -eq "extensionattribute15") { return "customAttribute15" }
elseif ($ldapProp -eq "facsimiletelephonenumber") { return "fax" }
elseif ($ldapProp -eq "garbagecollperiod") { return "RetainDeletedItemsFor" }
elseif ($ldapProp -eq "givenname") { return "FirstName" }
elseif ($ldapProp -eq "grouptype") { return "GroupType" }
elseif ($ldapProp -eq "objectguid") { return "Guid" }
elseif ($ldapProp -eq "hidedlmembership") { return "HiddenGroupMembershipEnabled" }
elseif ($ldapProp -eq "homemdb") { return "Database" }
elseif ($ldapProp -eq "homemta") { return "HomeMTA" }
elseif ($ldapProp -eq "homephone") { return "HomePhone" }
elseif ($ldapProp -eq "info") { return "Notes" }
elseif ($ldapProp -eq "initials") { return "Initials" }
elseif ($ldapProp -eq "internetencoding") { return "InternetEncoding" }
elseif ($ldapProp -eq "l") { return "City" }
elseif ($ldapProp -eq "legacyexchangedn") { return "LegacyExchangeDN" }
elseif ($ldapProp -eq "localeid") { return "LocaleID" }
elseif ($ldapProp -eq "mail") { return "WindowsEmailAddress" }
elseif ($ldapProp -eq "mailnickname") { return "Alias" }
elseif ($ldapProp -eq "managedby") { return "ManagedBy" }
elseif ($ldapProp -eq "manager") { return "Manager" }
elseif ($ldapProp -eq "mapirecipient") { return "MapiRecipient" }
elseif ($ldapProp -eq "mdboverhardquotalimit") { return "ProhibitSendReceiveQuota" }
elseif ($ldapProp -eq "mdboverquotalimit") { return "ProhibitSendQuota" }
elseif ($ldapProp -eq "mdbstoragequota") { return "IssueWarningQuota" }
elseif ($ldapProp -eq "mdbusedefaults") { return "UseDatabaseQuotaDefaults" }
elseif ($ldapProp -eq "member") { return "Members" }
elseif ($ldapProp -eq "memberof") { return "MemberOfGroup" }
elseif ($ldapProp -eq "mobile") { return "MobilePhone" }
elseif ($ldapProp -eq "msds-phoneticompanyname") { return "PhoneticCompany" }
elseif ($ldapProp -eq "msds-phoneticdepartment") { return "PhoneticDepartment" }
elseif ($ldapProp -eq "msds-phoneticdsiplayname") { return "PhoneticDisplayName" }
elseif ($ldapProp -eq "msds-phoneticfirstname") { return "PhoneticFirstName" }
elseif ($ldapProp -eq "msds-phoneticlastname") { return "PhoneticLastName" }
elseif ($ldapProp -eq "msexchassistantname") { return "AssistantName" }
elseif ($ldapProp -eq "msexchdynamicdlbasedn") { return "RecipientContainer" }
elseif ($ldapProp -eq "msexchdynamicdlfilter") { return "LdapRecipientFilter" }
elseif ($ldapProp -eq "msexchelcexpirysuspensionend") { return "ElcExpirationSuspensionEndDate" }
elseif ($ldapProp -eq "msexchelcexpirysuspensionstart") { return "ElcExpirationSuspensionStartDate" }
elseif ($ldapProp -eq "msexchelcmailboxflags") { return "ElcMailboxFlags" }
elseif ($ldapProp -eq "msexchexpansionservername") { return "ExpansionServer" }
elseif ($ldapProp -eq "msexchexternaloofoptions") { return "ExternalOofOptions" }
elseif ($ldapProp -eq "msexchhidefromaddresslists") { return "HiddenFromAddressListsEnabled" }
elseif ($ldapProp -eq "msexchhomeservername") { return "ServerLegacyDN" }
elseif ($ldapProp -eq "msexchmailboxfolderset") { return "MailboxFolderSet" }
elseif ($ldapProp -eq "msexchmailboxguid") { return "ExchangeGuid" }
elseif ($ldapProp -eq "msexchmailboxsecuritydescriptor") { return "ExchangeSecurityDescriptor" }
elseif ($ldapProp -eq "msexchmailboxtemplatelink") { return "ManagedFolderMailboxPolicy" }
elseif ($ldapProp -eq "msexchmasteraccountsid") { return "MasterAccountSid" }
elseif ($ldapProp -eq "msexchmaxblockedsenders") { return "MaxBlockedSenders" }
elseif ($ldapProp -eq "msexchmaxsafesenders") { return "MaxSafeSenders" }
elseif ($ldapProp -eq "msexchmdbrulesquota") { return "RulesQuota" }
elseif ($ldapProp -eq "msexchmessagehygieneflags") { return "MessageHygieneFlags" }
elseif ($ldapProp -eq "msexchmessagehygienescldeletethreshold") { return "SCLDeleteThresholdInt" }
elseif ($ldapProp -eq "msexchmessagehygienescljunkthreshold") { return "SCLJunkThresholdInt" }
elseif ($ldapProp -eq "msexchmessagehygienesclquarantinethreshold") { return "SCLQuarantineThresholdInt" }
elseif ($ldapProp -eq "msexchmessagehygienesclrejectthreshold") { return "SCLRejectThresholdInt" }
elseif ($ldapProp -eq "msexchmobilealloweddeviceids") { return "ActiveSyncAllowedDeviceIDs" }
elseif ($ldapProp -eq "msexchmobiledebuglogging") { return "ActiveSyncDebugLogging" }
elseif ($ldapProp -eq "msexchmobilemailboxflags") { return "MobileMailboxFlags" }
elseif ($ldapProp -eq "msexchmobilemailboxpolicylink") { return "ActiveSyncMailboxPolicy" }
elseif ($ldapProp -eq "msexchomaadminextendedsettings") { return "MobileAdminExtendedSettings" }
elseif ($ldapProp -eq "msexchomaadminwirelessenable") { return "MobileFeaturesEnabled" }
elseif ($ldapProp -eq "msexchpfrooturl") { return "PublicFolderRootUrl" }
elseif ($ldapProp -eq "msexchpftreetype") { return "PublicFolderType" }
elseif ($ldapProp -eq "msexchpoliciesexcluded") { return "PoliciesExcluded" }
elseif ($ldapProp -eq "msexchpoliciesincluded") { return "PoliciesIncluded" }
elseif ($ldapProp -eq "msexchprotocolsettings") { return "ProtocolSettings" }
elseif ($ldapProp -eq "msexchpurportedsearchui") { return "PurportedSearchUI" }
elseif ($ldapProp -eq "msexchquerybasedn") { return "QueryBaseDN" }
elseif ($ldapProp -eq "msexchqueryfilter") { return "RecipientFilter" }
elseif ($ldapProp -eq "msexchqueryfiltermetadata") { return "RecipientFilterMetadata" }
elseif ($ldapProp -eq "msexchrecipientdisplaytype") { return "RecipientDisplayType" }
elseif ($ldapProp -eq "msexchrecipienttypedetails") { return "RecipientTypeDetailsValue" }
elseif ($ldapProp -eq "msexchreciplimit") { return "RecipientLimits" }
elseif ($ldapProp -eq "msexchrequireauthtosendto") { return "RequireAllSendersAreAuthenticated" }
elseif ($ldapProp -eq "msexchresourcecapacity") { return "ResourceCapacity" }
elseif ($ldapProp -eq "msexchresourcedisplay") { return "ResourcePropertiesDisplay" }
elseif ($ldapProp -eq "msexchresourcemetadata") { return "ResourceMetaData" }
elseif ($ldapProp -eq "msexchresourcesearchproperties") { return "ResourceSearchProperties" }
elseif ($ldapProp -eq "msexchsafesendershash") { return "SafeSendersHash" }
elseif ($ldapProp -eq "msexchsaferecipientshash") { return "SafeRecipientsHash" }
elseif ($ldapProp -eq "msexchumaudiocodec") { return "CallAnsweringAudioCodec" }
elseif ($ldapProp -eq "msexchumdtmfmap") { return "UMDtmfMap" }
elseif ($ldapProp -eq "msexchumenabledflags") { return "UMEnabledFlags" }
elseif ($ldapProp -eq "msexchumlistindirectorysearch") { return "AllowUMCallsFromNonUsers" }
elseif ($ldapProp -eq "msexchumoperatornumber") { return "OperatorNumber" }
elseif ($ldapProp -eq "msexchumpinchecksum") { return "UMPinChecksum" }
elseif ($ldapProp -eq "msexchumrecipientdialplanlink") { return "UMRecipientDialPlanId" }
elseif ($ldapProp -eq "msexchumserverwritableflags") { return "UMServerWritableFlags" }
elseif ($ldapProp -eq "msexchumspokenname") { return "UMSpokenName" }
elseif ($ldapProp -eq "msexchumtemplatelink") { return "UMMailboxPolicy" }
elseif ($ldapProp -eq "msexchuseoab") { return "OfflineAddressBook" }
elseif ($ldapProp -eq "msexchuseraccountcontrol") { return "ExchangeUserAccountControl" }
elseif ($ldapProp -eq "msexchuserculture") { return "LanguagesRaw" }
elseif ($ldapProp -eq "msexchversion") { return "ExchangeVersion" }
elseif ($ldapProp -eq "name") { return "Name" }
elseif ($ldapProp -eq "ntsecuritydescriptor") { return "NTSecurityDescriptor" }
elseif ($ldapProp -eq "objectcategory") { return "ObjectCategory" }
elseif ($ldapProp -eq "objectclass") { return "ObjectClass" }
elseif ($ldapProp -eq "objectsid") { return "Sid" }
elseif ($ldapProp -eq "oofreplytooriginator") { return "SendOofMessageToOriginatorEnabled" }
elseif ($ldapProp -eq "otherfacsimiletelephonenumber") { return "OtherFax" }
elseif ($ldapProp -eq "otherhomephone") { return "OtherHomePhone" }
elseif ($ldapProp -eq "othertelephone") { return "OtherTelephone" }
elseif ($ldapProp -eq "pager") { return "Pager" }
elseif ($ldapProp -eq "pfcontacts") { return "PublicFolderContacts" }
elseif ($ldapProp -eq "physicaldeliveryofficename") { return "Office" }
elseif ($ldapProp -eq "postalcode") { return "PostalCode" }
elseif ($ldapProp -eq "postofficebox") { return "PostOfficeBox" }
elseif ($ldapProp -eq "primarygroupid") { return "PrimaryGroupId" }
elseif ($ldapProp -eq "proxyaddresses") { return "EmailAddresses" }
elseif ($ldapProp -eq "publicdelegates") { return "GrantSendOnBehalfTo" }
elseif ($ldapProp -eq "pwdlastset") { return "PasswordLastSetRaw" }
elseif ($ldapProp -eq "reporttooriginator") { return "ReportToOriginatorEnabled" }
elseif ($ldapProp -eq "reporttoowner") { return "ReportToManagerEnabled" }
elseif ($ldapProp -eq "samaccountname") { return "SamAccountName" }
elseif ($ldapProp -eq "showinaddressbook") { return "AddressListMembership" }
elseif ($ldapProp -eq "sidhistory") { return "SidHistory" }
elseif ($ldapProp -eq "sn") { return "LastName" }
elseif ($ldapProp -eq "st") { return "StateOrProvince" }
elseif ($ldapProp -eq "submissioncontlength") { return "MaxSendSize" }
elseif ($ldapProp -eq "streetaddress") { return "StreetAddress" }
elseif ($ldapProp -eq "targetaddress") { return "ExternalEmailAddress" }
elseif ($ldapProp -eq "telephoneassistant") { return "TelephoneAssistant" }
elseif ($ldapProp -eq "telephonenumber") { return "Phone" }
elseif ($ldapProp -eq "textencodedoraddress") { return "TextEncodedORAddress" }
elseif ($ldapProp -eq "title") { return "Title" }
elseif ($ldapProp -eq "unauthorig") { return "RejectMessagesFrom" }
elseif ($ldapProp -eq "unicodepwd") { return "UnicodePassword" }
elseif ($ldapProp -eq "useraccountcontrol") { return "UserAccountControl" }
elseif ($ldapProp -eq "usercertificate") { return "Certificate" }
elseif ($ldapProp -eq "userprincipalname") { return "UserPrincipalName" }
elseif ($ldapProp -eq "usersmimecertificate") { return "SMimeCertificate" }
elseif ($ldapProp -eq "whenchanged") { return "WhenChanged" }
elseif ($ldapProp -eq "whencreated") { return "WhenCreated" }
elseif ($ldapProp -eq "wwwhomepage") { return "WebPage" }
else { throw "Could not convert LDAP attribute '" + $ldapProp + "' to Opath." }
}
$script:filterString = $args[0]
if ($script:filterString.Length -gt 0)
{
convert-filter
}
else
{
write-host "No LDAP filter supplied."
}
#
#################################################################################
#
# This script is not officially supported by Microsoft, use it at your own risk.
# Microsoft has no liability, obligations, warranty, or responsibility regarding
# any result produced by use of this file.
#
#################################################################################
#
# Examples on ways to use this script in Powershell...
#
# To convert a manually entered filter and display the result:
#
# .\ConvertFrom-LdapFilter "(&(mailnickname=*))"
#
# To convert the LDAP filter on an existing address list and display the result:
#
# .\ConvertFrom-LdapFilter (Get-AddressList "My Address List").LdapRecipientFilter
#
# To convert the LDAP filter on an existing address list and update the address list with the new filter:
#
# Set-AddressList "My Address List" -RecipientFilter ( .\ConvertFrom-LdapFilter (Get-AddressList "My Address List").LdapRecipientFilter )
#
# To convert all existing legacy address lists and display the result without actually updating them:
#
# Get-AddressList | WHERE { $_.RecipientFilterType -eq 'Legacy' } | foreach { .\ConvertFrom-LdapFilter $_.LdapRecipientFilter }
#
# To convert all existing legacy address lists and output the name, current LDAP filter, and the generated OPATH to a tab-delimited file without actually updating the address lists:
#
# Get-AddressList | WHERE { $_.RecipientFilterType -eq 'Legacy' } | foreach { $_.Name + [char]9 + $_.LdapRecipientFilter + [char]9 + (.\ConvertFrom-LdapFilter $_.LdapRecipientFilter) } > C:\suggestedfilters.txt
#
# To convert all existing legacy address lists and actually update the address lists without prompting:
#
# Get-AddressList | WHERE { $_.RecipientFilterType -eq 'Legacy' } | foreach { Set-AddressList $_.Name -RecipientFilter (.\ConvertFrom-LdapFilter $_.LdapRecipientFilter) -ForceUpgrade }
#
# To convert all legacy address lists, GALs, and email address policies, without prompting, run three commands:
#
# Get-AddressList | WHERE { $_.RecipientFilterType -eq 'Legacy' } | foreach { Set-AddressList $_.Name -RecipientFilter (.\ConvertFrom-LdapFilter $_.LdapRecipientFilter) -ForceUpgrade }
# Get-GlobalAddressList | WHERE { $_.RecipientFilterType -eq 'Legacy' } | foreach { Set-GlobalAddressList $_.Name -RecipientFilter (.\ConvertFrom-LdapFilter $_.LdapRecipientFilter) -ForceUpgrade }
# Get-EmailAddressPolicy | WHERE { $_.RecipientFilterType -eq 'Legacy' } | foreach { Set-EmailAddressPolicy $_.Name -RecipientFilter (.\ConvertFrom-LdapFilter $_.LdapRecipientFilter) -ForceUpgrade }
#
trap
{
write-host $_.Exception.Message -fore Red
continue
}
function convert-filter
{
$output = BuildFilterFromString
return $output
}
function BuildFilterFromString
{
$script:filterString = $script:filterString.Trim()
[string[]]$conditions = GetConditionsFromString
if ($conditions.Length -gt 1)
{
throw "Invalid filter string."
}
return $conditions
}
function GetConditionsFromString
{
$script:filterString = $script:filterString.Trim()
$exitThisLevel = $false;
while (!($exitThisLevel))
{
# Special cases for default filters
# This is so that we match the ones given on the msexchangeteam.com blog
if ($script:filterString.StartsWith("(&(objectClass=user)(objectCategory=person)(mailNickname=*)(msExchHomeServerName=*))"))
{ # All Users
$script:filterString = $script:filterString.Remove(0, 83).Trim()
return "RecipientType -eq 'UserMailbox'"
}
if ($script:filterString.StartsWith("(& (mailnickname=*) (| (objectCategory=group) ))"))
{ # All Groups
$script:filterString = $script:filterString.Remove(0, 47).Trim()
return "( RecipientType -eq 'MailUniversalDistributionGroup' -or RecipientType -eq 'MailUniversalSecurityGroup' -or RecipientType -eq 'MailNonUniversalGroup' -or RecipientType -eq 'DynamicDistributionGroup' )"
}
if ($script:filterString.StartsWith("(& (mailnickname=*) (| (&(objectCategory=person)(objectClass=contact)) ))"))
{ # All Contacts
$script:filterString = $script:filterString.Remove(0, 72).Trim()
return "RecipientType -eq 'MailContact'"
}
if ($script:filterString.StartsWith("(& (mailnickname=*) (| (objectCategory=publicFolder) ))"))
{ # Public Folders
$script:filterString = $script:filterString.Remove(0, 54).Trim()
return "RecipientType -eq 'PublicFolder'"
}
if ($script:filterString.StartsWith("(& (mailnickname=*) (| (&(objectCategory=person)(objectClass=user)(!(homeMDB=*))(!(msExchHomeServerName=*)))(&(objectCategory=person)(objectClass=user)(|(homeMDB=*)(msExchHomeServerName=*)))(&(objectCategory=person)(objectClass=contact))(objectCategory=group)(objectCategory=publicFolder)(objectCategory=msExchDynamicDistributionList) ))"))
{ # Default Global Address List
$script:filterString = $script:filterString.Remove(0, 336).Trim()
return "( Alias -ne `$null -and (ObjectClass -eq 'user' -or ObjectClass -eq 'contact' -or ObjectClass -eq 'msExchSystemMailbox' -or ObjectClass -eq 'msExchDynamicDistributionList' -or ObjectClass -eq 'group' -or ObjectClass -eq 'publicFolder') )"
}
# End of default filter cases
if ($script:filterString.StartsWith("("))
{
$script:filterString = $script:filterString.Remove(0, 1).Trim()
}
else
{
throw "Invalid filter string."
}
if ($script:filterString.StartsWith("("))
{
GetConditionsFromString
}
else
{
$isNegative = $script:filterString.StartsWith("!")
$mustBeValueComparison = $false
if ($isNegative)
{
$script:filterString = $script:filterString.Remove(0, 1).Trim()
if ($script:filterString.StartsWith("("))
{
$script:filterString = $script:filterString.Remove(0, 1).Trim()
}
else
{
$mustBeValueComparison = $true
}
}
$op = ""
if ($script:filterString.StartsWith("|(homeMDB=*)(msExchHomeServerName=*))"))
{
$script:filterString = $script:filterString.Remove(0, 36)
$newCondition = " ( recipientType -eq 'UserMailbox' )"
if ($isNegative)
{
$newCondition = " -not (" + $newCondition + " )"
}
$newCondition
}
elseif ($script:filterString.StartsWith("&") -or $script:filterString.StartsWith("|"))
{
if ($mustBeValueComparison)
{
throw "Invalid filter string."
}
if ($script:filterString.StartsWith("&"))
{
$op = "and"
}
else
{
$op = "or"
}
$script:filterString = $script:filterString.Remove(0, 1).Trim()
if ($script:filterString.StartsWith("("))
{
[string[]]$theseConditions = GetConditionsFromString
$newCondition = ""
for ([int]$x = 0; $x -lt $theseConditions.Length; $x++)
{
$newCondition = $newCondition + $theseConditions[$x]
if (($x + 1) -lt $theseConditions.Count)
{
$newCondition = $newCondition + " -" + $op
}
}
if ($isNegative)
{
$newCondition = " -not (" + $newCondition + " )"
}
elseif ($theseConditions.Length -gt 1)
{
$newCondition = " (" + $newCondition + " )"
}
}
else
{
$newCondition = GetValueComparison
}
$newCondition
}
else # this better be a value comparison
{
GetValueComparison
}
if ($isNegative -and -not $mustBeValueComparison)
{
if ($script:filterString.StartsWith(")"))
{
$script:filterString = $script:filterString.Remove(0, 1).Trim()
}
else
{
throw "Invalid filter string."
}
}
if ($script:filterString.StartsWith(")"))
{
$script:filterString = $script:filterString.Remove(0, 1).Trim()
}
else
{
throw "Invalid filter string."
}
}
if (($script:filterString.StartsWith(")")) -or ($script:filterString.Length -eq 0))
{
$exitThisLevel = $true
}
}
return
}
function GetValueComparison
{
$operatorPos = $script:filterString.IndexOf("=")
$valuePos = $operatorPos + 1
if (($script:filterString[$operatorPos - 1] -eq '<') -or
($script:filterString[$operatorPos - 1] -eq '>'))
{
$operatorPos--
}
if ($operatorPos -lt 1)
{
throw "Invalid filter string."
}
$property = $script:filterString.Substring(0, $operatorPos).Trim()
$opstring = $script:filterString.Substring($operatorPos, $valuePos - $operatorPos)
$startPos = 0
# DN-valued attribute may contain parenthesis. Need to look for the end
# of the DN.
if ($property.ToLower() -eq "homemdb")
{
if (!($script:filterString[$valuePos] -eq '*'))
{
$startPos = $script:filterString.IndexOf(",DC=")
}
}
$endPos = $script:filterString.IndexOf(")", $startPos)
if ($endPos -lt 0)
{
throw "Invalid filter string."
}
$val = $script:filterString.Substring($valuePos, $endPos - $valuePos)
$script:filterString = $script:filterString.Substring($endPos)
[string]$compType = ""
if ($opstring -eq "=")
{
if ($val -eq "*")
{
$compType = "exists"
}
else
{
if ($val.IndexOf("*") -gt -1)
{
$compType = "like"
}
else
{
$compType = "equals"
}
}
}
elseif ($opstring -eq "<=")
{
$compType = "lessthanorequals"
}
elseif ($opstring -eq ">=")
{
$compType = "greaterthanorequals"
}
else
{
throw "Invalid filter string."
}
[string]$opathProp = GetOpathPropFromLdapProp $property
[string]$opathVal = GetOpathValFromLdapVal $opathProp $val
[string]$opathComparison = GetOpathComparisonFromLdapComparison $opathProp $compType $opathVal
$newCondition = " ( " + $opathProp + $opathComparison + " )"
if ($isNegative)
{
$newCondition = " -not " + $newCondition
}
$newCondition
}
function GetOpathComparisonFromLdapComparison([string]$opathProp, [string]$ldapComparison, [string]$opathVal)
{
if ($opathProp -eq "ObjectCategory" -and $ldapComparison -eq "equals")
{
return " -like '" + $opathVal + "'"
}
else
{
[string]$opathComparison = ""
if ($ldapComparison -eq "equals") { $opathComparison = " -eq '" }
elseif ($ldapComparison -eq "like") { $opathComparison = " -like '" }
elseif ($ldapComparison -eq "lessthanorequals") { $opathComparison = " -le '" }
elseif ($ldapComparison -eq "greaterthanorequals") { $opathComparison = " -ge '" }
elseif ($ldapComparison -eq "exists") { $opathComparison = " -ne `$null" }
else { throw "Could not convert unknown comparison type to OPATH comparison." }
if ($ldapComparison -ne "exists")
{
$opathComparison = $opathComparison + $opathVal + "'"
}
return $opathComparison
}
}
function GetOpathValFromLdapVal([string]$opathProp, [string]$ldapVal)
{
if ($opathProp -like "*Enabled")
{
$newBool = [System.Convert]::ToBoolean($ldapVal)
return "$" + $newBool.ToString().ToLower()
}
else
{
return $ldapVal
}
}
function GetOpathPropFromLdapProp([string]$ldapProp)
{
$ldapProp = $ldapProp.ToLower()
if ($ldapProp -eq "altrecipient") { return "ForwardingAddress" }
elseif ($ldapProp -eq "authorig") { return "AcceptMessagesOnlyFrom" }
elseif ($ldapProp -eq "c") { return "CountryOrRegion" }
elseif ($ldapProp -eq "canonicalname") { return "RawCanonicalName" }
elseif ($ldapProp -eq "cn") { return "CommonName" }
elseif ($ldapProp -eq "co") { return "Co" }
elseif ($ldapProp -eq "company") { return "Company" }
elseif ($ldapProp -eq "countrycode") { return "CountryCode" }
elseif ($ldapProp -eq "deleteditemflags") { return "DeletedItemFlags" }
elseif ($ldapProp -eq "deliveredirect") { return "DeliverToMailboxAndForward" }
elseif ($ldapProp -eq "delivcontlength") { return "MaxReceiveSize" }
elseif ($ldapProp -eq "department") { return "Department" }
elseif ($ldapProp -eq "description") { return "Description" }
elseif ($ldapProp -eq "directreports") { return "DirectReports" }
elseif ($ldapProp -eq "displayname") { return "DisplayName" }
elseif ($ldapProp -eq "displaynameprintable") { return "SimpleDisplayName" }
elseif ($ldapProp -eq "distinguisedname") { return "Id" }
elseif ($ldapProp -eq "dlmemrejectperms") { return "RejectMessagesFromDLMembers" }
elseif ($ldapProp -eq "dlmemsubmitperms") { return "AcceptMessagesOnlyFromDLMembers" }
elseif ($ldapProp -eq "extensionattribute1") { return "customAttribute1" }
elseif ($ldapProp -eq "extensionattribute2") { return "customAttribute2" }
elseif ($ldapProp -eq "extensionattribute3") { return "customAttribute3" }
elseif ($ldapProp -eq "extensionattribute4") { return "customAttribute4" }
elseif ($ldapProp -eq "extensionattribute5") { return "customAttribute5" }
elseif ($ldapProp -eq "extensionattribute6") { return "customAttribute6" }
elseif ($ldapProp -eq "extensionattribute7") { return "customAttribute7" }
elseif ($ldapProp -eq "extensionattribute8") { return "customAttribute8" }
elseif ($ldapProp -eq "extensionattribute9") { return "customAttribute9" }
elseif ($ldapProp -eq "extensionattribute10") { return "customAttribute10" }
elseif ($ldapProp -eq "extensionattribute11") { return "customAttribute11" }
elseif ($ldapProp -eq "extensionattribute12") { return "customAttribute12" }
elseif ($ldapProp -eq "extensionattribute13") { return "customAttribute13" }
elseif ($ldapProp -eq "extensionattribute14") { return "customAttribute14" }
elseif ($ldapProp -eq "extensionattribute15") { return "customAttribute15" }
elseif ($ldapProp -eq "facsimiletelephonenumber") { return "fax" }
elseif ($ldapProp -eq "garbagecollperiod") { return "RetainDeletedItemsFor" }
elseif ($ldapProp -eq "givenname") { return "FirstName" }
elseif ($ldapProp -eq "grouptype") { return "GroupType" }
elseif ($ldapProp -eq "objectguid") { return "Guid" }
elseif ($ldapProp -eq "hidedlmembership") { return "HiddenGroupMembershipEnabled" }
elseif ($ldapProp -eq "homemdb") { return "Database" }
elseif ($ldapProp -eq "homemta") { return "HomeMTA" }
elseif ($ldapProp -eq "homephone") { return "HomePhone" }
elseif ($ldapProp -eq "info") { return "Notes" }
elseif ($ldapProp -eq "initials") { return "Initials" }
elseif ($ldapProp -eq "internetencoding") { return "InternetEncoding" }
elseif ($ldapProp -eq "l") { return "City" }
elseif ($ldapProp -eq "legacyexchangedn") { return "LegacyExchangeDN" }
elseif ($ldapProp -eq "localeid") { return "LocaleID" }
elseif ($ldapProp -eq "mail") { return "WindowsEmailAddress" }
elseif ($ldapProp -eq "mailnickname") { return "Alias" }
elseif ($ldapProp -eq "managedby") { return "ManagedBy" }
elseif ($ldapProp -eq "manager") { return "Manager" }
elseif ($ldapProp -eq "mapirecipient") { return "MapiRecipient" }
elseif ($ldapProp -eq "mdboverhardquotalimit") { return "ProhibitSendReceiveQuota" }
elseif ($ldapProp -eq "mdboverquotalimit") { return "ProhibitSendQuota" }
elseif ($ldapProp -eq "mdbstoragequota") { return "IssueWarningQuota" }
elseif ($ldapProp -eq "mdbusedefaults") { return "UseDatabaseQuotaDefaults" }
elseif ($ldapProp -eq "member") { return "Members" }
elseif ($ldapProp -eq "memberof") { return "MemberOfGroup" }
elseif ($ldapProp -eq "mobile") { return "MobilePhone" }
elseif ($ldapProp -eq "msds-phoneticompanyname") { return "PhoneticCompany" }
elseif ($ldapProp -eq "msds-phoneticdepartment") { return "PhoneticDepartment" }
elseif ($ldapProp -eq "msds-phoneticdsiplayname") { return "PhoneticDisplayName" }
elseif ($ldapProp -eq "msds-phoneticfirstname") { return "PhoneticFirstName" }
elseif ($ldapProp -eq "msds-phoneticlastname") { return "PhoneticLastName" }
elseif ($ldapProp -eq "msexchassistantname") { return "AssistantName" }
elseif ($ldapProp -eq "msexchdynamicdlbasedn") { return "RecipientContainer" }
elseif ($ldapProp -eq "msexchdynamicdlfilter") { return "LdapRecipientFilter" }
elseif ($ldapProp -eq "msexchelcexpirysuspensionend") { return "ElcExpirationSuspensionEndDate" }
elseif ($ldapProp -eq "msexchelcexpirysuspensionstart") { return "ElcExpirationSuspensionStartDate" }
elseif ($ldapProp -eq "msexchelcmailboxflags") { return "ElcMailboxFlags" }
elseif ($ldapProp -eq "msexchexpansionservername") { return "ExpansionServer" }
elseif ($ldapProp -eq "msexchexternaloofoptions") { return "ExternalOofOptions" }
elseif ($ldapProp -eq "msexchhidefromaddresslists") { return "HiddenFromAddressListsEnabled" }
elseif ($ldapProp -eq "msexchhomeservername") { return "ServerLegacyDN" }
elseif ($ldapProp -eq "msexchmailboxfolderset") { return "MailboxFolderSet" }
elseif ($ldapProp -eq "msexchmailboxguid") { return "ExchangeGuid" }
elseif ($ldapProp -eq "msexchmailboxsecuritydescriptor") { return "ExchangeSecurityDescriptor" }
elseif ($ldapProp -eq "msexchmailboxtemplatelink") { return "ManagedFolderMailboxPolicy" }
elseif ($ldapProp -eq "msexchmasteraccountsid") { return "MasterAccountSid" }
elseif ($ldapProp -eq "msexchmaxblockedsenders") { return "MaxBlockedSenders" }
elseif ($ldapProp -eq "msexchmaxsafesenders") { return "MaxSafeSenders" }
elseif ($ldapProp -eq "msexchmdbrulesquota") { return "RulesQuota" }
elseif ($ldapProp -eq "msexchmessagehygieneflags") { return "MessageHygieneFlags" }
elseif ($ldapProp -eq "msexchmessagehygienescldeletethreshold") { return "SCLDeleteThresholdInt" }
elseif ($ldapProp -eq "msexchmessagehygienescljunkthreshold") { return "SCLJunkThresholdInt" }
elseif ($ldapProp -eq "msexchmessagehygienesclquarantinethreshold") { return "SCLQuarantineThresholdInt" }
elseif ($ldapProp -eq "msexchmessagehygienesclrejectthreshold") { return "SCLRejectThresholdInt" }
elseif ($ldapProp -eq "msexchmobilealloweddeviceids") { return "ActiveSyncAllowedDeviceIDs" }
elseif ($ldapProp -eq "msexchmobiledebuglogging") { return "ActiveSyncDebugLogging" }
elseif ($ldapProp -eq "msexchmobilemailboxflags") { return "MobileMailboxFlags" }
elseif ($ldapProp -eq "msexchmobilemailboxpolicylink") { return "ActiveSyncMailboxPolicy" }
elseif ($ldapProp -eq "msexchomaadminextendedsettings") { return "MobileAdminExtendedSettings" }
elseif ($ldapProp -eq "msexchomaadminwirelessenable") { return "MobileFeaturesEnabled" }
elseif ($ldapProp -eq "msexchpfrooturl") { return "PublicFolderRootUrl" }
elseif ($ldapProp -eq "msexchpftreetype") { return "PublicFolderType" }
elseif ($ldapProp -eq "msexchpoliciesexcluded") { return "PoliciesExcluded" }
elseif ($ldapProp -eq "msexchpoliciesincluded") { return "PoliciesIncluded" }
elseif ($ldapProp -eq "msexchprotocolsettings") { return "ProtocolSettings" }
elseif ($ldapProp -eq "msexchpurportedsearchui") { return "PurportedSearchUI" }
elseif ($ldapProp -eq "msexchquerybasedn") { return "QueryBaseDN" }
elseif ($ldapProp -eq "msexchqueryfilter") { return "RecipientFilter" }
elseif ($ldapProp -eq "msexchqueryfiltermetadata") { return "RecipientFilterMetadata" }
elseif ($ldapProp -eq "msexchrecipientdisplaytype") { return "RecipientDisplayType" }
elseif ($ldapProp -eq "msexchrecipienttypedetails") { return "RecipientTypeDetailsValue" }
elseif ($ldapProp -eq "msexchreciplimit") { return "RecipientLimits" }
elseif ($ldapProp -eq "msexchrequireauthtosendto") { return "RequireAllSendersAreAuthenticated" }
elseif ($ldapProp -eq "msexchresourcecapacity") { return "ResourceCapacity" }
elseif ($ldapProp -eq "msexchresourcedisplay") { return "ResourcePropertiesDisplay" }
elseif ($ldapProp -eq "msexchresourcemetadata") { return "ResourceMetaData" }
elseif ($ldapProp -eq "msexchresourcesearchproperties") { return "ResourceSearchProperties" }
elseif ($ldapProp -eq "msexchsafesendershash") { return "SafeSendersHash" }
elseif ($ldapProp -eq "msexchsaferecipientshash") { return "SafeRecipientsHash" }
elseif ($ldapProp -eq "msexchumaudiocodec") { return "CallAnsweringAudioCodec" }
elseif ($ldapProp -eq "msexchumdtmfmap") { return "UMDtmfMap" }
elseif ($ldapProp -eq "msexchumenabledflags") { return "UMEnabledFlags" }
elseif ($ldapProp -eq "msexchumlistindirectorysearch") { return "AllowUMCallsFromNonUsers" }
elseif ($ldapProp -eq "msexchumoperatornumber") { return "OperatorNumber" }
elseif ($ldapProp -eq "msexchumpinchecksum") { return "UMPinChecksum" }
elseif ($ldapProp -eq "msexchumrecipientdialplanlink") { return "UMRecipientDialPlanId" }
elseif ($ldapProp -eq "msexchumserverwritableflags") { return "UMServerWritableFlags" }
elseif ($ldapProp -eq "msexchumspokenname") { return "UMSpokenName" }
elseif ($ldapProp -eq "msexchumtemplatelink") { return "UMMailboxPolicy" }
elseif ($ldapProp -eq "msexchuseoab") { return "OfflineAddressBook" }
elseif ($ldapProp -eq "msexchuseraccountcontrol") { return "ExchangeUserAccountControl" }
elseif ($ldapProp -eq "msexchuserculture") { return "LanguagesRaw" }
elseif ($ldapProp -eq "msexchversion") { return "ExchangeVersion" }
elseif ($ldapProp -eq "name") { return "Name" }
elseif ($ldapProp -eq "ntsecuritydescriptor") { return "NTSecurityDescriptor" }
elseif ($ldapProp -eq "objectcategory") { return "ObjectCategory" }
elseif ($ldapProp -eq "objectclass") { return "ObjectClass" }
elseif ($ldapProp -eq "objectsid") { return "Sid" }
elseif ($ldapProp -eq "oofreplytooriginator") { return "SendOofMessageToOriginatorEnabled" }
elseif ($ldapProp -eq "otherfacsimiletelephonenumber") { return "OtherFax" }
elseif ($ldapProp -eq "otherhomephone") { return "OtherHomePhone" }
elseif ($ldapProp -eq "othertelephone") { return "OtherTelephone" }
elseif ($ldapProp -eq "pager") { return "Pager" }
elseif ($ldapProp -eq "pfcontacts") { return "PublicFolderContacts" }
elseif ($ldapProp -eq "physicaldeliveryofficename") { return "Office" }
elseif ($ldapProp -eq "postalcode") { return "PostalCode" }
elseif ($ldapProp -eq "postofficebox") { return "PostOfficeBox" }
elseif ($ldapProp -eq "primarygroupid") { return "PrimaryGroupId" }
elseif ($ldapProp -eq "proxyaddresses") { return "EmailAddresses" }
elseif ($ldapProp -eq "publicdelegates") { return "GrantSendOnBehalfTo" }
elseif ($ldapProp -eq "pwdlastset") { return "PasswordLastSetRaw" }
elseif ($ldapProp -eq "reporttooriginator") { return "ReportToOriginatorEnabled" }
elseif ($ldapProp -eq "reporttoowner") { return "ReportToManagerEnabled" }
elseif ($ldapProp -eq "samaccountname") { return "SamAccountName" }
elseif ($ldapProp -eq "showinaddressbook") { return "AddressListMembership" }
elseif ($ldapProp -eq "sidhistory") { return "SidHistory" }
elseif ($ldapProp -eq "sn") { return "LastName" }
elseif ($ldapProp -eq "st") { return "StateOrProvince" }
elseif ($ldapProp -eq "submissioncontlength") { return "MaxSendSize" }
elseif ($ldapProp -eq "streetaddress") { return "StreetAddress" }
elseif ($ldapProp -eq "targetaddress") { return "ExternalEmailAddress" }
elseif ($ldapProp -eq "telephoneassistant") { return "TelephoneAssistant" }
elseif ($ldapProp -eq "telephonenumber") { return "Phone" }
elseif ($ldapProp -eq "textencodedoraddress") { return "TextEncodedORAddress" }
elseif ($ldapProp -eq "title") { return "Title" }
elseif ($ldapProp -eq "unauthorig") { return "RejectMessagesFrom" }
elseif ($ldapProp -eq "unicodepwd") { return "UnicodePassword" }
elseif ($ldapProp -eq "useraccountcontrol") { return "UserAccountControl" }
elseif ($ldapProp -eq "usercertificate") { return "Certificate" }
elseif ($ldapProp -eq "userprincipalname") { return "UserPrincipalName" }
elseif ($ldapProp -eq "usersmimecertificate") { return "SMimeCertificate" }
elseif ($ldapProp -eq "whenchanged") { return "WhenChanged" }
elseif ($ldapProp -eq "whencreated") { return "WhenCreated" }
elseif ($ldapProp -eq "wwwhomepage") { return "WebPage" }
else { throw "Could not convert LDAP attribute '" + $ldapProp + "' to Opath." }
}
$script:filterString = $args[0]
if ($script:filterString.Length -gt 0)
{
convert-filter
}
else
{
write-host "No LDAP filter supplied."
}
If you don’t use any LDAP filtering in your Recipient Policies you can convert the Recipient Policies directly to Email Address Policies.
The Set-EmailAddressPolicy cmdlet is needed for this.
Open the Exchange Management Shell and enter the following command:
Get-EmailAddressPolicy | where {$_.RecipientFilterType –eq “Legacy”}
This will show a list of Recipient Policies that are available in your Exchange organization. We can use this output by piping it into the Set-EmailAddressPolicy cmdlet:
Get-EmailAddressPolicy | where {$_.RecipientFilterType –eq “Legacy”} |
Set-EmailAddressPolicy –IncludedRecipients AllRecipients
Set-EmailAddressPolicy –IncludedRecipients AllRecipients
The Recipient Policies are now converted to Exchange Server 2010 Email Address Policies and you can open them in the Exchange Management Console. Please note that the examples mentioned above are pretty simple policies. If you have more complex policies please test this thoroughly. If you have any Mailbox Manager policies, these have to be removed.
Warning:
if you happen to do this on Recipient Policies that have (advanced) LDAP queries, all custom filters can be reset to "mailnickname=*" which can result significant email outages. You have to test all these changes in a dedicated lab environment to see how these changes will affect your Exchange environment!
The Address Lists need to be converted to Exchange Server 2010 as well. To achieve this open an Exchange Management Shell and enter the following commands:
Set-AddressList “All Users” –IncludedRecipients MailboxUsers
Set-AddressList “All Groups” –IncludedRecipients Mailgroups
Set-AddressList “All Contacts” –IncludedRecipients MailContacts
Set-AddressList “Public Folders” –RecipientFilter {RecipientType –eq “PublicFolder”}
Set-GlobalAddressList "Default Global Address List" -RecipientFilter {(Alias -ne $null -and (ObjectClass -eq 'user' -or ObjectClass -eq 'contact'
-or ObjectClass -eq 'msExchSystemMailbox' -or ObjectClass
-eq 'msExchDynamicDistributionList' -or ObjectClass -eq 'group'
-or ObjectClass -eq 'publicFolder'))}
Set-AddressList “All Groups” –IncludedRecipients Mailgroups
Set-AddressList “All Contacts” –IncludedRecipients MailContacts
Set-AddressList “Public Folders” –RecipientFilter {RecipientType –eq “PublicFolder”}
Set-GlobalAddressList "Default Global Address List" -RecipientFilter {(Alias -ne $null -and (ObjectClass -eq 'user' -or ObjectClass -eq 'contact'
-or ObjectClass -eq 'msExchSystemMailbox' -or ObjectClass
-eq 'msExchDynamicDistributionList' -or ObjectClass -eq 'group'
-or ObjectClass -eq 'publicFolder'))}
When finished you can open all Address Lists using the Exchange Management Console and using the Exchange 2003 System Manager for opening the Address Lists is no longer possible.
Mail flow settings
Before changing the actual SMTP mailflow we have to create a Send Connector first. This will allow the Hub Transport Server to send SMTP mail to the Internet directly. In the Exchange Management Console, navigate to the Organization Configuration and select the Hub Transport Server. In the Actions Pane select “New Send Connector…” and create a new SMTP connector to the Internet. Select * in the namespace (this will send all outbound messages go through this connector) and select the DNS or the Smarthost option, depending on your own situation
By default the Receive Connector on the Exchange 2010 Hub Transport Server will not allow any anonymous connections. To change this open the Exchange Management Console, navigate to the Server Configuration and select the Hub Transport Server in the Results Pane. Right Click the default Receive Connector and select its properties. Select the Permissions tab and check the “anonymous” option to enable SMTP anonymous access.
Now that everything is in place, we can start moving the messaging services to Exchange Server 2010. Although there’s no hard requirement to start with the mail flow I’m going to start here. In the original configuration, mail from the Internet is delivered to the ISA 2006 Server and from there it is sent to the Exchange 2003 front-end server. We’ll change the ISA Server configuration so that SMTP mail is delivered to the Exchange Server 2010 Hub Transport Server. When a mailbox is still on Exchange Server 2003 the message is sent across the Interop Routing Group Connector from Exchange Server 2010 to Exchange Server 2003 where it is delivered to the intended Recipient. The Interop Routing Group Connector was created during setup of the Hub Transport Server as explained in the previous chapter. On the ISA 2006 Server open the ISA Server Management Console and navigate to the Firewall Policy. In the results pane select the SMTP rule and edit it so SMTP messages are delivered to the new Exchange 2010 Hub Transport Server.
Outbound SMTP traffic needs to be changed as well. In the original situation there was an SMTP connector from the Exchange Server 2003 Front-End Server towards the Internet. A new Send Connector on the Exchange Server 2010 Hub Transport Server needs to be created that will replace the old Exchange Server 2003 SMTP Connector.
Log on to the Exchange Server 2010 Hub Transport Server and open the Exchange Management Console. Navigate to the Organization Configuration and select the Hub Transport. In the Results Pane select the Send Connectors tab and select “New Send Connector” in the Actions Pane and follow the wizard to create a new Send Connector. In the Address Space windows select “*” as the address space to make sure all messages are routed through this connector. In the Network Settings window you have to select either to use DNS (the Hub Transport Server will send all messages to other hosts) or to use a smart host (the Hub Transport Server will forward all messages to this host which in turn will send it to all other hosts).
If the new Send Connector is working, the SMTP Connector on the Exchange Server 2003 Front-End Server can be removed. If removed, messages from Exchange Server 2003 mailboxes bound to the Internet go through the Interop Routing Group Connector to the Exchange Server 2010 Hub Transport Server and then through the Send Connector to the Internet.
Client Access Server
In the previous article regarding the upgrade from Exchange Server 2003 to Exchange Server 2010 I explained the different namespaces. On the Exchange Server 2010 Client Access Server there’s a certificate with the following names:
•Webmail.inframan.nl
•Autodiscover.inframan.nl
•Legacy.inframan.nl
When an OWA client logs on to the Exchange Server 2010 Client Access Server and the particular mailbox is still on Exchange Server 2003 the client gets redirected to the Exchange Server 2003 front-end server. This server will have the legacy. Inframan.nl name, since two servers cannot have the same Fully Qualified Domain Name (webmail.inframan.nl).
The new certificate on the Exchange Server 2010 Client Access Server can be exported and imported on the Exchange Server 2003 Front-End Server. This way an error message will not be shown when a client gets redirected to the Exchange Server 2003 Front-End Server.
Note. The certificate needs to be imported on the ISA 2006 Server as well.
After importing the new certificate on the Exchange Server 2003 Front-End server and the ISA 2006 Server the clients continue working, but with the new certificate, so you’ll face only a small downtime (one minute) here when replacing the certificate.
Changing the ISA 2006 Server rules takes a bit more planning. Three new rules will be created:
•Exchange 2010 OWA rule;
•Exchange 2010 ActiveSync rule;
•Exchange 2010 Outlook Anywhere and Autodiscover rule;
Do not Apply the changes to the ISA Server at this moment, but uncheck the ‘enable’ option on each rule to prevent immediate activation.
For the ‘old’ Exchange 2003 legacy environment three rules have to be created on the ISA 2006 Server as well:
•Exchange 2003 OWA rule;
•Exchange 2003 ActiveSync rule;
•Exchange 2003 RPC over HTTP rule (this one can be combined with the previous rule however);
As with the Exchange 2010 do not apply these rules immediately, but uncheck the ‘enable’ option on every rule before applying these changes.
The Web Listener in ISA 2006 Server needs to be changed as well. Since a seamless experience for end-users is needed when the redirection occurs, the Single Sign-On option need to be enabled on the Web Listener.
In the ISA Server Management Console open the properties of the Web Listener and navigate to the SSO tab. Add the .inframan.nl in the SSO domain, please note the leading dot.
When you have configured the above options it’s time to apply all changes in the ISA Server. Enable the 2010 firewall rules, enable the legacy Exchange 2003 rules and disable the old Exchange 2003 rules. All clients are now connected to the Exchange Server 2010 Client Access Server and when needed the clients are redirected to the Exchange Server 2003 Front-End Server.
In the ISA Server Management Console open the properties of the Web Listener and navigate to the SSO tab. Add the .inframan.nl in the SSO domain, please note the leading dot.
When you have configured the above options it’s time to apply all changes in the ISA Server. Enable the 2010 firewall rules, enable the legacy Exchange 2003 rules and disable the old Exchange 2003 rules. All clients are now connected to the Exchange Server 2010 Client Access Server and when needed the clients are redirected to the Exchange Server 2003 Front-End Server.
Move Mailboxes ... continued below