When planning a mailbox migration to Exchange Server 2007 you should consider the amount of transaction logging that will be generated by the move.  In low risk environments circular logging can be used to avoid disk space problems caused by the volume of transaction logs generated during bulk mailbox moves.

You can query the current state of circular logging on your storage groups with the Get-StorageGroup cmdlet.

[PS] C:\>Get-StorageGroup | fl name, circularloggingenabled

Name                   : SG1 Staff A-L
CircularLoggingEnabled : False

Name                   : SG2 Staff M-Z
CircularLoggingEnabled : False

Name                   : SG4 Public Folders
CircularLoggingEnabled : False

Name                   : SG3 Service Accounts
CircularLoggingEnabled : False

To enable circular logging use the Set-StorageGroup cmdlet.  You can enable circular logging on all storage groups together by piping a Get-StorageGroup command to Set-StorageGroup.

Get-StorageGroup | Set-StorageGroup -CircularLoggingEnabled $true

Get-StorageGroup will now reflect the change.

[PS] C:\>Get-StorageGroup | fl name, circularloggingenabled

Name                   : SG1 Staff A-L
CircularLoggingEnabled : True

Name                   : SG2 Staff M-Z
CircularLoggingEnabled : True

Name                   : SG4 Public Folders
CircularLoggingEnabled : True

Name                   : SG3 Service Accounts
CircularLoggingEnabled : True

Use Set-StorageGroup again to disable circular logging after your migration is complete.

Get-StorageGroup | Set-StorageGroup -CircularLoggingEnabled $false

A lot has been said in the Exchange community about the decision by Microsoft to remove (or not provide) Exchange Server 2007 awareness from the built-in backup utility shipped with Windows Server 2007.  The MS Exchange Team blog explains that a little here :

About 2 years ago, when the Exchange team started testing Exchange 2007 on Windows 2008, we found that the built-in backup application had changed dramatically. Decisions that drove that change by the Windows team are not the subject of this post, but it is fair to say that the Windows team did not make the decision lightly.

When we evaluated the features of Windows Server Backup, it was clear that the backup and restore experience on Windows 2008 would not be the experience that existing Exchange customers have been used to for so long. Because we had feedback from several customers who told us they would rather get a more full-featured backup solution for their Exchange servers, a decision was made not to provide an Exchange-aware backup solution for Windows 2008 in Exchange 2007 Service Pack 1.

This week they announced the following:

Although we can’t share all of the details now, we thought that this issue was important enough to announce a decision we recently made. We have decided to develop and release a VSS-based plug-in for Windows Server Backup that will enable you to properly backup and restore Exchange 2007 with a built-in Windows 2008 backup application.

This is good news for Exchange customers looking for inexpensive backup solutions.  I’m a bit curious though about this statement:

While you will be able to backup and restore Exchange 2007 on Windows 2008, you should not expect feature parity with the Windows 2003 NTBackup experience. There will not be the same level granularity and control that NTBackup provides and backups will be limited to the local server only.

NT Backup was about as featureless as you could get when it comes to Exchange backups, so I don’t quite understand how you can take a step backward from that.  It will be interesting to see the result when it ships thats for sure.

Project Coconut entries:

The mailboxes have all been moved and the new Exchange Server 2007 system is bedding in.  During and after your mailbox migration you may find one or two issues appear with some users’ mailbox access.

Classfactory error when moving mailbox to Exchange Server 2007

Some mailboxes may be reported as failed in your mailbox move report, with the following error information:

Error occurred in the step: Opening source mailbox. Failed to open mailbox with error: ClassFactory cannot supply requested class, error code: -1056749262.

Check the properties of the account in Active Directory Users & Computers and you should find that the account is disabled.  Exchange will not move a mailbox for a disabled user account.  Your options here are to enable the account temporarily while you move the mailbox, or just delete the mailbox from your legacy Exchange server.

Users unable to access Outlook Web Access after mailbox moves

Some users may report that they are not able to access OWA after their mailbox has been moved to the Exchange Server 2007 server.

Check the properties of the account in Active Directory Users & Computers and verify that in the Security tab the account is configured to inherit permissions.  If the tick box is cleared you should tick it and apply the change.

Removing legacy Exchange servers from the organisation

Microsoft has published some good guidance on removing your legacy servers from the Exchange organisation here on Technet.  Lets go through the steps here.

1. Move all mailboxes to an Exchange Server 2007 server in the organisation.  I’ve already covered that in the last part of this series.

2. Move all content from the public folder database on the legacy server to a public folder database on an Exchange 2007 server in the organization.

Exchange 2003 permits you to do this via the Exchange System Manager console.  Navigate to your legacy Exchange server and drill down to the Public Folder store.  Right click and select “Move all replicas”.

This operation can take some time for large public folder trees.  The move may also generate a lot of transaction logging and therefore a lot of disk IO on both the source and target server.  If the public folder databases are sharing disk with other databases or mail queues then you may want to consider doing this outside of business hours.

3. Move the OAB generation to the Exchange Server 2007 server.  A simple way of moving all OABs to the Exchange Server 2007 server is using the Exchange Management Console with the Get-OfflineAddressBook and Move-OfflineAddressBook cmdlets.

[PS] C:\>Get-OfflineAddressBook | Move-OfflineAddressBook -Server LABEX2 -confir
m:$false
WARNING: Do not turn off public folder publishing for offline address book
(OAB) “\Default Offline Address List” before it is generated on the target
server “LABEX2″. If you turn off public folder publishing prematurely, the
entire OAB will be downloaded for all users who are associated with this OAB.

4. Remove public folder and mailbox stores.  You can do this by simply right-clicking and deleting the databases in Exchange System Manager.  However, Exchange will not permit you to delete a public folder store that still contains replicas, nor a mailbox store that still contains mailboxes.  System Manager will display an error that one or more users currently use this mailbox store (ID no: c1034a7f).

You can locate these stragglers using Active Directory Users & Computers.  Right-click the root of the domain and start a search.  Leave the first criteria blank and click on the Exchange tab.  Tick “Show only Exchange recipients” and “Users with Exchange mailbox”.  Click Find Now, and then add the Exchange Home Server column using the View menu.  Sort by this column and you should quickly see which users Exchange still thinks have mailboxes on the legacy server.

If the users don’t really have a mailbox you can right-click and remove their Exchange attributes.

5. Verify that internet mail is configured to route through your Exchange Server 2007 servers.  You can configure your Hub Transport server to send and receive internet mail using the instructions here.

6. Verify inbound protocol services point to an Exchange Server 2007 Client Access Server.  You can read about publishing Exchange 2007 with ISA Server 2006 here.

7. Delete the routing group connectors that connect the Exchange 2003 or Exchange 2000 routing groups and the Exchange 2007 routing group.  You can do this quickly and easily using the Get-RoutingGroupConnector and Remove-RoutingGroupConnector cmdlets.

[PS] C:\>Get-RoutingGroupConnector | Remove-RoutingGroupConnector -confirm:$fals
e

8. Remove Exchange 2003 or Exchange 2000 recipient policies that are only Mailbox Manager policies.

9. If you have Exchange 2003 or Exchange 2000 policies that are both E-mail Addresses and Mailbox Manager policies, remove the Mailbox Manager part of the policy.

10. Move the Public Folder hierarchy from the legacy Exchange admin group to the Exchange Server 2007 admin group.  To do this in Exchange System Manager right click the Exchange 2007 admin group and create a new Public Folders container.

 Then, drag the Public Folder tree from the legacy admin group to the Public Folder container you just created.

11. Delete the Recipient Update Services.  You can delete the domain RUS via Exchange System Manager, but the Enterprise RUS must be deleted via ADSIEdit.msc.  So you may as well use ADSIEdit.msc to delete them all.

12. Uninstall Exchange 2000/2003 from the server.  If any of the above steps have not been completed properly Exchange will not allow you to uninstall it via Add/Remove Programs.  However, if you are able to set the action to Remove then all requirements have been met and Exchange will uninstall.  You will often need your Exchange media available for the uninstallation.

So, what next?

I’ve now completed the minimum steps required to transition the Exchange 2003 organisation to Exchange 2007, however there are still tasks that should be performed on the Exchange 2007 server to finish the job.  You should consider upgrading your Email Address Policies and your Address List objects to Exchange 2007.  Though this is not strictly required, it pays to get it out of the way so you don’t run in to problems later on when you want to edit them

The Microsoft Exchange Team Blog has a great writeup of how to go about doing this here.

Uprading Email Address Policies

To find any legacy EAPs in the organisation you can run a filtered Get-EmailAddressPolicy command.

[PS] C:\>Get-EmailAddressPolicy | where { $_.RecipientFilterType -eq “Legacy” }
| Format-List Name,*RecipientFilter*,ExchangeVersion

Name                       : Default Policy
RecipientFilter            :
LdapRecipientFilter        : (mailnickname=*)
LastUpdatedRecipientFilter :
RecipientFilterApplied     : False
RecipientFilterType        : Legacy
ExchangeVersion            : 0.0 (6.5.6500.0)

This will reveal all “Legacy” EAPs and their RecipientFilter details.  To upgrade the Default Policy with its simple filter you can run the following Set-EmailAddressPolicy command.

[PS] C:\>Set-EmailAddressPolicy “Default Policy” -IncludedRecipients AllRecipients
Confirm
To save changes on object “Default Policy”, the object must be upgraded to the
current Exchange version. After the upgrade, this object cannot be managed by a
 previous version of Exchange System Manager. Do you want to continue to
upgrade and save the object?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help
(default is “Y”):y

Upgrading Address List Objects

Legacy Address Lists can be located using a filtered Get-AddressList cmdlet.

[PS] C:\>Get-AddressList | where {$_.RecipientFilterType -eq “Legacy”} | Format-
List Name,*RecipientFilter*,ExchangeVersion

Name                       : All Users
RecipientFilter            :
LdapRecipientFilter        : (& (mailnickname=*) (| (&(objectCategory=person)(o
                             bjectClass=user)(!(homeMDB=*))(!(msExchHomeServerN
                             ame=*)))(&(objectCategory=person)(objectClass=user
                             )(|(homeMDB=*)(msExchHomeServerName=*))) ))
LastUpdatedRecipientFilter :
RecipientFilterApplied     : False
RecipientFilterType        : Legacy
ExchangeVersion            : 0.0 (6.5.6500.0)

Name                       : All Groups
RecipientFilter            :
LdapRecipientFilter        : (& (mailnickname=*) (| (objectCategory=group) ))
LastUpdatedRecipientFilter :
RecipientFilterApplied     : False
RecipientFilterType        : Legacy
ExchangeVersion            : 0.0 (6.5.6500.0)

Name                       : All Contacts
RecipientFilter            :
LdapRecipientFilter        : (& (mailnickname=*) (| (&(objectCategory=person)(o
                             bjectClass=contact)) ))
LastUpdatedRecipientFilter :
RecipientFilterApplied     : False
RecipientFilterType        : Legacy
ExchangeVersion            : 0.0 (6.5.6500.0)

Name                       : Public Folders
RecipientFilter            :
LdapRecipientFilter        : (& (mailnickname=*) (| (objectCategory=publicFolde
                             r) ))
LastUpdatedRecipientFilter :
RecipientFilterApplied     : False
RecipientFilterType        : Legacy
ExchangeVersion            : 0.0 (6.5.6500.0)

These Address Lists can be upgraded using the Set-AddressList cmdlet.

[PS] C:\>Set-AddressList “All Users” -IncludedRecipients MailboxUsers

[PS] C:\>Set-AddressList “All Groups” -IncludedRecipients MailGroups

[PS] C:\>Set-AddressList “All Contacts” -IncludedRecipients MailContacts

[PS] C:\>Set-AddressList “Public Folders” -RecipientFilter { RecipientType -eq ‘
PublicFolder’ }

The default Global Address List can also be upgraded using the Set-GlobalAddressList cmdlet.

[PS] C:\>Set-GlobalAddressList “Default Global Address List” -RecipientFilter {(
Alias -ne $null -and (ObjectClass -eq ‘user’ -or ObjectClass -eq ‘contact’ -or O
bjectClass -eq ‘msExchSystemMailbox’ -or ObjectClass -eq ‘msExchDynamicDistribut
ionList’ -or ObjectClass -eq ‘group’ -or ObjectClass -eq ‘publicFolder’))}

Confirm
To save changes on object “Default Global Address List”, the object must be
upgraded to the current Exchange version. After the upgrade, this object cannot
 be managed by a previous version of Exchange System Manager. Do you want to
continue to upgrade and save the object?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help
(default is “Y”):y

For non-default Address List and Global Address List objects some analysis of the custom LDAP filters will be required to determine how to go about upgrading them.  You can refer to the Evan Dodd’s blog post here for more details.

Is that it?

That is all for this Project Coconut series of posts, however there is a lot more to talk about with Exchange Server 2007 which I look forward to writing about.

Project complete.

The Microsoft Exchange Team Blog has released guidance for some of the most common Standby Continuous Replication issues.  It discusses the following issues:

Read more here.

Project Coconut entries:

Now that the Exchange server is installed and configured it is time to migrate the mailboxes. You can take a look at the existing mailboxes in the Exchange organisation using the Exchange Management Console or using the Get-Mailbox cmdlet in the Exchange Management Shell.

mailboxmigration003

[PS] C:\>Get-Mailbox

Name                      Alias                ServerName       ProhibitSendQuo
                                                                ta
—-                      —–                ———-       —————
Administrator             Administrator        labex1           unlimited
User1                     User1                labex1           unlimited
User2                     User2                labex1           unlimited
User3                     User3                labex1           unlimited
User4                     User4                labex1           unlimited
John Adams                johnadams            labex1           unlimited
Paul Anderson             paulanderson         labex1           unlimited
Gary Billups              garybillups          labex1           unlimited
Frank Curtin              frankcurtin          labex1           unlimited
Harry Kindle              harrykindle          labex1           unlimited
Carl Munro                carl munro           labex1           unlimited
WARNING: Object lab.internal/Lab Corp/Users/Carl Munro has been corrupted and
it is in an inconsistent state. The following validation errors have occurred:
WARNING: “carl munro” is not valid for Alias. Valid values are: Strings formed
with characters from a to z (uppercase or lowercase), digits from 0 to 9, !, #,
 $, %, &, ‘, *, +, -, /, =, ?, ^, _, `, {, |, } or ~. One or more periods may
be embedded in an alias, but each one of them should be preceded and followed
by at least one of the other characters. Unicode characters from U+00A1 to
U+00FF are also valid in an alias, but they will be mapped to a best-fit
US-ASCII string in the email address which is generated from such an alias.

The first thing you might notice is the warning about an invalid alias on one of the mailbox users. The EMC and EMS will warn you of any such problems with mailboxes and you should take steps to fix them before you attempt the mailbox migration. With just one invalid alias it is easy to fix, but if you have dozens or even hundreds of them you’ll need some scripting assistance. Fortunately the Microsoft Exchange Team has come up with a script to make this easy.

Consider Transaction Logging

Bulk mailbox migrations generate a lot of transaction logging on the target server, as each mailbox item moved is a line in a log file. This can cause disk space problems on even very large capacity volumes, which is a problem you definitely want to avoid as running out of disk space will cause the databases in that storage group to dismount.

There are two approaches you can take to work around this:

I generally recommend the second approach as circular logging carries some risks. By migrating the mailboxes in smaller batches you allow your support staff to better handle any unforeseen problems that arise because they will only affect smaller numbers of users. It also makes the migrations easier to schedule in limited non-business hours. And finally it encourages a post-migration backup of the database which is just a plain good idea. In real life I tend to aim for a 2-3 hour window for mailbox moves in the evening and then launch a backup and go to sleep.

How to Migrate in Batches

The Exchange Management Console makes it very simple to migrate users in batches by simply using filters to limit your view of mailboxes to just those you wish to migrate. For example, if I planned on migrating all users with surnames starting with “A” I could apply such a filter easily.

mailboxmigration002

Similarly I could plan to move users according to which Mailbox Database they are on, and filter on that criteria.

mailboxmigration004

You can also use the Exchange Management Shell to move users who match certain criteria. To move all users with surnames starting with “A” using the Exchange Management Shell I can pipe a Get-User query into the Move-Mailbox cmdlet.

[PS] C:\>Get-User | where {$_.RecipientType -eq “UserMailbox” -and $_.LastName -
like “A*”} | Move-Mailbox -TargetDatabase “Mailbox Database” -Confirm:$false

Using -Confirm:$false ensures that I am not prompted for each mailbox move.

mailboxmigration005

In the next part of Project Coconut I’ll discuss some of the post-migration issues you may encounter, and go through the process of removing the legacy Exchange servers from the organisation.