Zoho Banner September 2011

Archive for the 'Exchange Server' Category

Search Result differences with Export-Mailbox

I came across an anomaly with the Exchange 2007 Export-Mailbox cmdlet at a customer site recently.  It created a major inconvenience for some bulk mailbox exports, so I thought I would share it here.  Basically, I was able to generate two different search results depending on whether or not I specified a PST file as target.  I’ve since managed to reproduce the behaviour in my own test lab, so the problem appears to be generic and not limited to the specific customer’s environment.

This is what my test environment looks like:

Mailox Server  = Windows Server 2008 SP2 with Exchange Server 2007 SP2 RU5

Export workstation = Windows 7 SP1 with Outlook 2010 and Exchange Server 2007 SP2 RU5 Management Tools

My goal was to export all items that contain the string [blah] (including the square brackets) to a target.  If I specify a PST file as the target then all items that contain the specified string are exported to the PST file as expected, e.g.

Export-Mailbox -Identity c781e3a3-1e08-40a7-abab-ba71b9dddc0b -AllContentKeywords “[blah]” `
-DeleteContent:$false -DeleteAssociatedMessages:$false -PSTFolderPath $pstpath -Confirm:$false

However if I specify a folder in another mailbox as the target and use the same search string then items matching [blah] are copied to the target as well as all items matching blah (i.e. without the square brackets), e.g.

Export-Mailbox -Identity c781e3a3-1e08-40a7-abab-ba71b9dddc0b -AllContentKeywords “[blah]” `
-TargetFolder “EM” -TargetMailbox d4aa986b-c33c-4a89-9e08-1a3ceb5c796e `
-DeleteContent:$false -DeleteAssociatedMessages:$false -Confirm:$false

As you can see, the string passed to the AllContentKeywords parameter is exactly the same in both examples, but the result is different. 

I haven’t yet found a reasonable explanation for why this is happening, but it seems that the search behaviour is different depepending on whether or not the cmdlet includes the option to export to PST.  For example, a straight delete using export-mailbox (i.e. no target at all) will also match both [blah] and blah:

Export-Mailbox -Identity c781e3a3-1e08-40a7-abab-ba71b9dddc0b -AllContentKeywords “[blah]” `
-DeleteContent:$true -DeleteAssociatedMessages:$true -Confirm:$false

However combining the delete option with an export to PST will just match on [blah].

My guess is that the PST option somehow causes the cmdlet to use a different search method (or index?).  When the PST option isn’t used the cmdlet simply ignores the square brackets (and I guess any other special characters).  I haven’t yet found a way to escape the special characters to ensure they are included in all searches.  If anyone knows how to do this, please let me know.

GAL Sync with Powershell

If you’re looking for a Global Address List synchronisation solution for Exchange that simply uses Powershell, look no further than this excellent script from fellow MVP Carol Wapshere.

http://www.wapshere.com/missmiis/a-galsync-powershell-script

The script doesn’t leverage the DirSync control (and hence doesn’t use deltas), which means that it isn’t perhaps as efficient as some of the full-blown solutions out there, but it has the beauty of simplicity!  Another advantage is that it doesn’t require any expensive infrastructure components - unlike most solutions that need at least one dedicated server and a database.

It also works with a variety of Exchange versions!

The script is likely to be most useful for SMEs during migration scenarios. Larger organisations or those looking for something long-term are more likely to invest in a more comprehensive solution such as FIM, SimpleSync or Quest ActiveRoles QuickConnect.

I encourage you to check it out.

Microsoft Exchange MAPI and CDO 1.2.1 with no Public Folders

 

I came across a problem the other day when using version 6.5.8211.0 of Microsoft Exchange MAPI and CDO 1.2.1 on a server running Good Mobile Messaging.  The Good software accesses user mailboxes via the MAPI CDO client.  At first the mailbox access was failing horribly with the following errors:

2011-03-11 13:24:33 12:00  ERROR:-2147219707
2011-03-11 13:24:33 12:00  MSG:Code:IDispatch error #1285 Source:Collaboration Data Objects Description:The attempt to log on to the Microsoft Exchange Server computer has failed. [Microsoft Exchange Server Information Store - [MAPI_E_FAILONEPROVIDER(8004011D)]]

The MAPI_E_FAILONEPROVIDER error appears to be fairly generic and I couldn’t find anything on the Microsoft Knowledge Base that matched my scenario.

In the end the problem turned out to be a by-product of my Exchange 2010 SP1 environment not having any Public Folders.  Apparently the MAPI CDO client will by default look for Public Folders when accessing the mailbox and will throw the error if it can’t find any. 

The fix is to add a registry key to the server running MAPI CDO that sets a flag (CONNECT_IGNORE_NO_PF) that instructs the client to ignore the absence of Public Folders.

  1. On the computer running Microsoft Exchange MAPI and CDO 1.2.1, click Start > Run.
  2. In the Open field, type regedit.
  3. Click OK.
  4. Perform one of the following actions:
    • If you are running a 32-bit version of Windows, navigate to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Messaging Subsystem\CDO.
    • If you are running a 64-bit version of Windows, navigate to HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows Messaging Subsystem.

  5. If the CDO registry key does not exist, create a registry key that you name CDO.
  6. In the CDO registry key, if the DWORD value does not exist, create a DWORD value that you name Ignore No PF.
  7. Change the DWORD value to 1.
  8. Click OK.

Source: Technet

Interestingly, the only references I could find to the “Ignore No PF” key were some MSDN and Technet blogs and the support documentation for Blackberry Enterprise Server.  There is currently nothing available in the Microsoft on-line documentation, including the Knowledge Base (at least nothing I could find). Given that Public Folders are being “de-emphasised” within Exchange I would have thought this workaround would be given much more prominence.

Tony

Quest ActiveRoles Quick Connect Express: GAL Sync Step-by-step Guide

A couple of weeks ago I blogged about using Quest’s ActiveRoles Quick Connect Express for Exchange 2010 Global Address List synchronisation (GAL Sync).  Since then I’ve written a step-by-step guide which will hopefully help others who want to use this very useful freeware utility.  You can download the guide (pdf format) here:

GAL Sync with ActiveRoles Quick Connect Express - Step-by-Step Guide v1

I have also updated the Powershell script that exposes the provisioned Contact objects in the target GAL.  You can download the script here:

ConfigureContacts.ps1

If you have any feedback on the guide please post a comment here or contact me directly (tony@activedir.org)

GAL Sync with Quest Quick Connect Express for Active Directory

Quest has just released a freeware product called Quick Connect Express for Active Directory. If you’re looking for something that fills the gap left by the (now pensionable) Microsoft Identity Integration Feature Pack, then this may well be it.  I’ve spent the last day looking at the product’s capabilities for running Exchange 2010 Global Address List synchronisation and I have to say I’ve very impressed.  Aside from the price tag ($0.00 suits the pocket of most), the best thing about QQCE is that it’s really easy to set up and configure.

At the time of writing the download link points to the wrong version of Quick Connect.  I only worked this out when the installer prompted me for a connection to the ActiveRoles Server Administration Service (something not used with the Express version).  I’m sure Quest will sort this out soon, but in the meantime, you can obtain the correct version by registering with the Quest Support web site and downloading the software and associated documentation from there.  You should end up with the following two files:

  • Quest_QuickConnectSyncEngineStandaloneModex64_470.msi (this is the 64-bit version – a 32-bit version is also available)
  • QuickConnectStandaloneMode_4.7_AdminGuide.pdf

Optionally, you can also download the Quick Connect Powershell provider:

  • Quest_QuickConnectManagementShellStandaloneModex64_470.msi

I chose to install the software on a Windows Server 2008 R2 Standard Edition machine together with SQL Server 2008 R2.  QQCE uses SQL databases to store the synchronisation data, but SQL Server doesn’t need to be on the same machine.

If I have time I’ll work on a step-by-step guide for GAL Sync using QQCE, but in the meantime here are some of the configuration details I used in my lab. ***Update Jan 2011 - step-by-step guide now available***

My first forest (ad.contoso.com) runs Windows Server 2008 R2 functional level and has Exchange 2010 SP1 RU2.  The second forest (ad.fabrikam.com) has the same versions.  I joined the server running QQCE to the CONTOSOE domain, but it could equally have been joined to the FABRIKAM domain.  I then configured GAL Sync in the direction CONTOSO –> FABRIKAM.  In other words, I had users in CONTOSO that I wanted to appears as Contacts in the FABRIKAM Global Address List.  Of course it is also possible to perform two-way GAL sync with the tool – I just didn’t take it that far.

Once you have completed the installation, the first thing to do is select one of the two domains as the “Managed Domain” for QQCE.  For the purposes of GAL sync the selection is arbitrary.  You then configure the second domain as a “Connected System”.

qqc_connections1

You then need to set up the workflow.  I chose to configure three separate workflow steps for the GAL Sync (Provisioning, Update and Deprovisioning).  This ensures that any creation, modification or deletion of mailbox-enabled users in CONTOSO are reflected in FABRIKAM.

The provisioning aspect of the workflow requires the most work.  The tool can easily be configured to provision Contact objects in the target, but a custom post-sync Powershell script is required to ensure the contacts appear in the GAL.

qqc_provisoning1

My script (which you can download here) invokes a remote Powershell session against a FABRIKAM Exchange server and uses the Get-Contact and Set-Contact cmdlets to ensure the attributes required for GAL visibility are stamped on the Contact objects.

qqc_provisoning_script

When configuring the Source information, I specified the OU containing the mailbox-enabled User objects and identified them using the homeMDB attribute.  If the homeMDB attribute is present on a User object you can assume it is mailbox-enabled.

qqc_provisoning2

The Target window in the configuration wizard allows you to specify what object type to create (Contact in my case).  You also specify the rule(s) for generating the object name. I chose the source User object’s Display Name attribute to generate the name (cn) for the corresponding Contact object.

 qqc_provisoning3

Finally, you specify which attributes on the source object should be populated on the target object during provisioning.  My choices are fairly obvious, but note in particular that I used the mail attribute from the source to create the Contact object’s targetAddress attribute.  The targetAddress attribute is important for Contacts as it is the one Exchange uses for routing purposes.

qqc_provisoning4

The Update and Deprovisioning steps are much simpler to configure, so I won’t show them here. 

Once the workflow setup is compete you can configure them to run according to a schedule that you specify.  Once per day is probably sufficient in most cases.

The remaining task is to create a mapping rule for the User->Contact relationship.  This is required to allow the Update and Deprovisioning workflow steps to match the correct target object based on changes or deletions in the source domain.

qqc_workflow1

And that’s it really.  You can pretty much have the whole thing up and running in an hour or less!

Much kudos to Quest for pushing this out as a free tool.  Of course GAL Synchronisation is not the sole purpose of the tool, but I suspect it’ll be the major drawcard for many organisations given its usefulness in migration and coexistence scenarios.  The major alternatives for GAL Sync with Exchange 2010 are ILM/FIM and SimplSync, both of which cost money and, in the case of FIM at least, require a great deal more configuration effort.

Tony

Powershell script to install Windows Updates from folder

 

If you’ve been working with Exchange 2010 Service Pack 1 you will know that there are several pre-requisites to download and install. Once downloaded you end up with a bunch of *.msu (Windows Update) files.  If, like me, you have to install them on several servers and don’t like the idea of having to double-click to install them via the UI you look for ways to simplify the process.  Powershell struck me as the obvious solution, but I couldn’t find any cmdlets that manage Windows Updates.  There are some examples, such as this from James O’Neill, but which are somewhat too elaborate for what I wanted to do.  In the end I wrote a small script (below) that calls wusa.exe to install the updates.  Not the prettiest method.  Hopefully Microsoft will provide set of cmdlets to manage Windows Updates in the next version of Windows.

#########################################################
#
# Name: InstallWindowsUpdates.ps1
# Author: Tony Murray
# Version: 1.0
# Date: 16/11/2010
# Comment: PowerShell script to install
# Windows Update files
#
#########################################################

# Specify the location of the *.msu files
$updatedir = "C:\E2010 SP1 Prereqs\"
###

$files = Get-ChildItem $updatedir -Recurse
$msus = $files | ? {$_.extension -eq ".msu"}

foreach ($msu in $msus)
{
    write-host "Installing update $msu ..."
    $fullname = $msu.fullname
    # Need to wrap in quotes as folder path may contain spaces
    $fullname = "`"" + $fullname + "`""
    # Specify the command line parameters for wusa.exe
    $parameters = $fullname + " /quiet /norestart"
    # Start wusa.exe and pass in the parameters
    $install = [System.Diagnostics.Process]::Start( "wusa",$parameters )
    $install.WaitForExit()
    write-host "Finished installing $msu"
}

write-host "Restarting Computer"
#Restart-Computer

If someone has a better method for doing this, please let me know.

Exchange Extension Attributes – A Cautionary Tale

I had always been under the impression that the custom attributes introduced by the Exchange schema extensions were handy for all sorts of things.  Earlier this week I discovered that there are hidden dangers when using them for anything other than Exchange-related purposes.

When you prepare the schema for Exchange you will see, amongst others, 15 new attributes named extensionattribute1 to extensionAttribute15 (common name ms-Exch-Extension-Attribute-n).  These attributes are exposed via the UI tools, which makes them user-friendly to administrators and support staff.

These custom attributes have a Unicode string syntax, so you can store just about any information you might need in them.  They also form part of attribute set replicated via the Global Catalog and are indexed in AD.  All of these things make the attributes useful as generic “bucket” to store user or group-related information without the hassle of developing your own schema extensions.

extensionAttribute1

As an example, Quest Migration Manager defaults to using two extension attributes (14 and 15) when it detects that the required Exchange schema extensions are in place.  QMM uses these as service attributes to support synchronisation and migration. 

Sounds perfect right?  Well I thought so until I discovered the other day the attribute values are blown away when mailbox-enabling or mailbox-disabling a user account.  For example, when you disable a mailbox it disconnects it from the parent AD user object and at the same time strips the user object of all its Exchange-related attribute value, including the extension attributes.  The Disable-Mailbox cmdlet does this silently and without warning - like a thief in the night!

It would be nice if Exchange could just leave these attributes alone.  The fact that they are subject to being summarily cleared means that (for me at least) they shouldn’t be used to store anything other than Exchange-related information.

Powershell script to bulk convert linked mailboxes

As part of a recent domain migration, I had to convert a number of linked mailboxes to standard “user” mailboxes.  The well known method for converting linked mailboxes is to disconnect the mailbox, change the type and then reconnect.  This is fine you just have a few linked mailboxes to deal with, but not if you have a whole lot. 

I found a great script written by Georg Hinterhofer that seemed to be just what I needed.  When I tried the script it failed because the values for $AclContainingAEA show as being in the form <domain>\<user>.  Normally, this would be ok, but in my case the user objects involved had been migrated with SIDHistory.  This mean that the $AclContainingAEA values were interpreted by the script as being from the target domain, when in fact behind the scenes the values corresponded to the SID from the source domain.  It meant I had to do a little trickery to get the script to work for my scenario.  My update to the script is here: convertlinkedmailbox.txt

Georg wrote the script for Exchange 2007,  but it works equally well for Exchange 2010.

Error when trying to fix a corrupted search catalog

I had a problem in my lab environment yesterday when trying to fix a corrupted search catalog on one of my Exchange 2010 mailbox servers.  I knew the search catalog was corrupted because I was seeing the following events:

Log Name:      Application
Source:        ExchangeStoreDB
Date:          21/06/2010 12:02:03 p.m.
Event ID:      123
Task Category: Database recovery
Level:         Error
Keywords:      Classic
User:          N/A
Computer:      MXB02.contoso.com
Description:
At ‘21/06/2010 12:02:01 p.m.’ the Microsoft Exchange Information Store Database ‘DB01′ copy on this server experienced a corrupted search catalog. Consult the event log on the server for other “ExchangeStoreDb” and “MSExchange Search Indexer” events for more specific information about the failure. Reseeding the catalog is recommended via the ‘Update-MailboxDatabaseCopy’ task.

I knew I had a good copy of the database on my other server (MBX01), so I went ahead and issued the following Powershell command:

Update-MailboxDatabaseCopy -Identity “DB01\MBX02″ -CatalogOnly

This generated a nasty looking erorr, which corresponded to the following Application event log entry:

Log Name:      Application
Source:        MSExchange Configuration Cmdlet - Remote Management
Date:          21/06/2010 4:54:08 p.m.
Event ID:      4
Task Category: General
Level:         Error
Keywords:      Classic
User:          N/A
Computer:      MBX02.contoso.com
Description:
(PID 9940, Thread 21) Task Update-MailboxDatabaseCopy writing error when processing record of index 0. Error: Microsoft.Exchange.Cluster.Replay.CiSeederGenericException: A server-side seed operation has failed. Error: An error occurred while performing the seed operation, which may indicate a problem with the source disk. Error: An error occurred while updating the search catalog files from server ‘MBX01′ to ‘MBX02′. Error: Can’t dismount the search catalog. Error: Microsoft.Exchange.Search.Common.FteCatalogNotFoundException: SearchCatalog.Dismount failed, error 0×80043629 —> System.ComponentModel.Win32Exception: Unknown error (0×80043629)
   — End of inner exception stack trace —
   at Microsoft.Exchange.Cluster.Replay.CiFilesSeederInstance.<>c__DisplayClass5.<SeedThreadProcInternal>b__2(Object , EventArgs )
   at Microsoft.Exchange.Cluster.Replay.CiFilesSeederInstance.RetryCiOperation(EventHandler evt) —> Microsoft.Exchange.Search.Common.FteCatalogNotFoundException: SearchCatalog.Dismount failed, error 0×80043629 —> System.ComponentModel.Win32Exception: Unknown error (0×80043629)
   — End of inner exception stack trace —
   at Microsoft.Exchange.Cluster.Replay.CiFilesSeederInstance.<>c__DisplayClass5.<SeedThreadProcInternal>b__2(Object , EventArgs )
   at Microsoft.Exchange.Cluster.Replay.CiFilesSeederInstance.RetryCiOperation(EventHandler evt)
   — End of inner exception stack trace (Microsoft.Exchange.Search.Common.FteCatalogNotFoundException) —
   at Microsoft.Exchange.Cluster.Replay.CiFilesSeederInstance.SeedThreadProcInternal()
   at Microsoft.Exchange.Data.Storage.Cluster.HaRpcExceptionWrapperBase`2.RunRpcServerOperation(String databaseName, RpcServerOperation rpcOperation)
   — End of stack trace on server (MBX02.contoso.com) —
   at Microsoft.Exchange.Data.Storage.Cluster.HaRpcExceptionWrapperBase`2.ClientRethrowIfFailed(String databaseName, String serverName, RpcErrorExceptionInfo errorInfo)
   at Microsoft.Exchange.Cluster.Replay.SeedProgressReporter.GetException()
Event Xml:

After some fruitless retries and even more fruitless Googling, I finally found a Technet article that indicates I should have suspended the database copy before running the Update-MailboxDatabaseCopy command.  Sure enough, once I suspended the database copy I was able to run the command successfully.

Interestingly (and somewhat worryingly) the corrupted search index appeared immediately after an attempt to perform a server switchover.  If I didn’t know better I would think that the switchover generated the corruption. ;-)

Hopefully this will help others who run into the same problem.

Error when uninstalling Exchange 2010 from server

The other day I had to uninstall Exchange 2010 from a server with the CAS and Hub Transport roles.  It all went well until the point where it was uninstalling the Hub Transport role.  The uninstall then ground to a halt with the following error:

Log Name:      Application
Source:        MSExchange Configuration Cmdlet - Management Console
Date:          20/05/2010 4:11:01 p.m.
Event ID:      4
Task Category: General
Level:         Error
Keywords:      Classic
User:          N/A
Computer:      HUBCAS1.contoso.com
Description:
(PID 6920, Thread 31) Task Uninstall-MsiPackage writing error when processing record of index 0. Error: Microsoft.Exchange.Configuration.Tasks.TaskException: Couldn’t open package ‘D:\Program Files\Microsoft\Exchange Server\V14\Mailbox\MSFTE.MSI’. Another version of this product is already installed. Installation of this version cannot continue. To configure or remove the existing version of this product, use Add/Remove Programs on the Control Panel. Error code is 1638. —> System.ComponentModel.Win32Exception: Another version of this product is already installed. Installation of this version cannot continue. To configure or remove the existing version of this product, use Add/Remove Programs on the Control Panel
   — End of inner exception stack trace —
   at Microsoft.Exchange.Management.Deployment.MsiUtility.GetProductCode(String packagePath)
   at Microsoft.Exchange.Management.Deployment.MsiUtility.IsInstalled(String packagePath)
   at Microsoft.Exchange.Management.Deployment.UninstallMsi.InternalValidate()

After scratching my head for a few minutes, I uninstalled Update Rollup 3 for Exchange Server 2010 and then re-tried the uninstall for Exchange.  It went through perfectly. 

I hadn’t realised it was necessary to remove any Update Rollups before uninstalling Exchange, but it it seems it is required in this case.

Next Page »