Exchange 2010 Gotcha – #4

Public Folder Contacts Can’t Replicate

If you have a public folder contact that includes an e-mail address, there is also an e-mail address type field that is associated with every e-mail address.

Note: You cannot see this e-mail address type field by default – but it’s still there. To view it, go to a Contacts folder in Outlook and create a custom view. In that view, add “Full Name”, then select “E-Mail Address Fields” and add “E-Mail Address” and “E-Mail Address Type”. Now, examine the Contacts in the folder using the custom view. You’ll see e-mail address types such as “SMTP” for external Internet contacts, “EX” for internal organization e-mail contacts, “FAX” if you have a fax connector installed, etc.

Now, Exchange 2003 (and perhaps Exchange 2007 – I have not checked in my lab) allowed two differerent e-mail address types to indicate “SMTP”. I believe this to be a hold-over from Outlook 97, although I have no documented proof of that (but in Outlook 97 we had “Internet mode” and “Corporate or Workgroup mode” – so it makes sense). The two different types are “SMTP” and “POP3/INTERNET”.

“POP3/INTERNET” is not valid in Exchange 2010. If you attempt to replicate a public folders to Exchange 2010 that contains this e-mail address type, the replication will abort. Thankfully, you do receive an event log error message that provides SOME clues about this occurring. The error looks like this:

Event Type:      Error
Event Source:    MSExchange Store Driver
Event Category:  (1)
Event ID:        1020
Date:            5/11/2010
Time:            10:00:43 AM
User:            N/A
Computer:        exchmb2.example.com
Description:
The store driver couldn't deliver the public folder replication message "Folder Content Backfill Response (exchmb1-IS@example.com)" because the following error occurred: Property validation failed. Property = [{00062004-0000-0000-c000-000000000046}:0x8082] Email1AddrType Error = The length of the property is too long. The maximum length is 9 and the length of the value provided is 13... For more information, see Help and Support Center at http://go.microsoft.com/fwlink/events.asp.

What you will have to do is, using Outlook, obtain a list of all the affected contacts as described above, and also using Outlook, change the address type to SMTP.

In Outlook 2010, you can directly edit this field. In Outlook 2007, you will need to open each contact, right click on the e-mail address in the default display, and select Properties. Then, for the Address Type field, click the “Internet” button (this changes the e-mail address type to “SMTP” – the button will now display “Custom”). Then “Save and Close” the updated contact.

In my migrations, I’ve only had a maximum of about 150 of these. If you have thousands, you will probably need to consider writing a webdav application/script to run against the Exchange 2003 server(s).

Until next time…

If there are things you would like to see written about, please let me know.


Follow me on twitter: @EssentialExch

MAPI in the registry (Or, setting the “use HTTP first” boxes via VBScript)

First off, I didn’t use PowerShell because I use the script in this article as a login script – and while I’m sure that the Windows Scripting Host is installed everywhere, I can’t be sure that PowerShell is installed everywhere. It will be a couple of years before I can do that.

Beginning with Exchange 2003 and Outlook 2003 (when running on Windows 2003), you could use RPC/HTTP (the feature was renamed to Outlook Anywhere with Exchange 2007). RPC/HTTP provides the capability of encapsulating the native protocol that Outlook uses to communicate with Exchange Server with a secure HTTP tunnel. Long story short, it’s a way of safely getting around firewalls.

The name of the protocol that Outlook prefers to use with Exchange Server is called MAPI – Message Applications Programming Interface. Let’s suffice it to say that MAPI is very powerful, very extensible, allows you to do darn near anything with a message or with Exchange that you might ever want to, and as is typical with all that power – MAPI is complicated to use. And you won’t be using MAPI in a script!

I can’t give MAPI justice in a blog post. But let’s talk about a few basic MAPI concepts.

Providers – a MAPI provider is some type of a server process (note: this does NOT mean that it has to run on a server, just that it provides services to clients). A few sample MAPI providers include the Address Book provider, the Spooler (which queues and sends email to Exchange), and the Profile provider (which is responsible for managing Mail profiles on a per-user basis on a client workstation).

Profile – a MAPI profile defines everything that a messaging client (such as Outlook) may need to know about communicating with an email server. A single profile may contain information about all of the various providers available to the client, both locally and on remote servers.

Property – a MAPI property is no different than any other type of property. It contains a value that is relevant to a specific provider and that value is contained within a specific profile. In general, a MAPI property is referred to via something called a PROP_TAG (a property tag) which is a 32 bit binary value. The first 16 bits represent the type of the property (such as integer or string, etc.) plus a special flag bit or two. The second 16 bits of a property is the specific property identifier.

The profile provider, which can be accessed via raw MAPI (of course), uses the system registry to store information about MAPI properties, profiles, providers, and other MAPI objects. Officially, these items are opaque. However, they have been the same since Windows 95, so it’s unlikely that they will be changing any time soon.

In the registry, each MAPI service associated with a particular profile has a GUID, which is a string. The particular GUID is assigned to the MAPI service, and is consistent across all MAPI installations. Each MAPI service has a series of property values assigned to it, and those property tags are represented by an 8-character value which is the hexidecimal representation of the binary property tag.

Today, we are particular interested in a single MAPI service – the Exchange Server Details MAPI service. This service is responsible for the connectivity to an Exchange server via the MAPI protocol. It has the following GUID:

Const ExchDetails = “13dbb0c8aa05101a9bb000aa002fc45a

EVERY MAPI profile which connects to an Exchange server will have that MAPI service defined and its property values populated. The particular MAPI property we are interested in is named PR_ROH_FLAGS. It looks like this:

Const PT_LONG = “0003” ‘ hex MAPI type for a 4-byte binary value

PR_ROH_FLAGS = PT_LONG & “6623” ‘ PROP_TAG (PT_LONG, 0x6623)

therefore the resultant value for PR_ROH_FLAGS is 00036623. Any MAPI profile which currently (or ever) was using RPC/HTTP (Outlook Anywhere) will have this property present. This flags value contains a number of documented (and conceivably undocumented) flags. They are:

” Connect to my Exchange mailbox by using HTTP.
Const ROHFLAGS_USE_ROH = &h1

” Connect by using SSL only.
Const ROHFLAGS_SSL_ONLY = &h2

” Mutually authenticate the session when connecting by using SSL.
Const ROHFLAGS_MUTUAL_AUTH = &h4

” On fast networks, connect by using HTTP first. Then, connect by using TCP/IP.
Const ROHFLAGS_HTTP_FIRST_ON_FAST = &h8

” On slow networks, connect by using HTTP first. Then, connect by using TCP/IP.
Const ROHFLAGS_HTTP_FIRST_ON_SLOW = &h20

You should note that the first flag (ROHFALGS_USE_ROH) indicates whether or not RPC over HTTP is enabled within this profile. The second flag (ROHFLAGS_SSL_ONLY) will always be set in the current implementation. If the ROHFLAGS_MUTUAL_AUTH flag is set, it means that both the client and the server will authenticate to each other.

The last two flags are the ones we are interested in… ROHFLAGS_HTTP_FIRST_ON_FAST and ROHFLAGS_HTTP_FIRST_ON_SLOW. They define whether HTTP is tried first, or TCP is tried first. If the boxes are checked, the flags are set. Conversely, if the flags are set, the boxes will be checked. Therefore, our goal is to make sure those flags are set.

Especially if you are using Basic authentication, having these flags set can result in faster Outlook startup time.

By default, Autodiscover in Exchange 2007 and above will set the ROHFLAGS_HTTP_FIRST_ON_SLOW flag, but not set the ROHFLAGS_HTTP_FIRST_ON_FAST flag. There is no way to change this behavior.

The following script is much longer than an equivalent script in PowerShell would be, and it’s longer than it has to be in VBScript, but I wanted to make it easy to understand and provide resources for other scripters wanting to make profile modifications.

Obligatory disclaimers:

Modifying your registry can break your computer.

Modifying MAPI properties by modifying the registry may not be supported, I really don’t know. It works for me and my clients, but I can’t guarantee that it will for you.

On to the script:

''
'' httpFirstAlways.vbs
''
''
'' Michael B. Smith
'' michael@TheEssentialExchange.com
'' July, 2009
''
'' No warranties express or implied are available.
'' Use at your own risk - but it works for me!
''
'' This routine, for the current user, scans through all Exchange profiles. If
'' the RPC over HTTP (Outlook Anywhere) flags value is present, this means that
'' RPC over HTTP is configured for the profile. If the flag is present, this
'' routine will force "On fast networks, connect using HTTP first" and "On slow
'' networks, connect using HTTP first" to be checked.
''
Const ProfilePath = "Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles"
Const ExchDetails = "13dbb0c8aa05101a9bb000aa002fc45a" ' Exchange Server Details MAPI service

Const PT_LONG     = "0003" ' hex MAPI type for a 4-byte binary value
COnst PT_UNICODE  = "001f" ' hex MAPI type for a Unicode string

' Used to configure cached mode, but not used in this script

Dim PR_CONFIG_FLAGS          ' configuration flags for the Exchange Server Details MAPI service

PR_CONFIG_FLAGS          = PT_LONG    & "6601" ' PROP_TAG (PT_LONG, 0x6601)

'' MAPI properties for RPC over HTTP
'' From KB 898835 - MAPI properties for RPC over HTTP settings
'' http://support.microsoft.com/kb/898835

Dim PR_ROH_FLAGS             ' RPC over HTTP flags
Dim PR_ROH_PROXY_SERVER      ' RPC over HTTP proxy server
Dim PR_ROH_PRINCIPAL_NAME    ' Primary name on the SSL certificate 
Dim PR_ROH_PROXY_AUTH_SCHEME ' Basic or NTLM

PR_ROH_FLAGS             = PT_LONG    & "6623" ' PROP_TAG (PT_LONG,    0x6623)
PR_ROH_PROXY_SERVER      = PT_UNICODE & "6622" ' PROP_TAG (PT_UNICODE, 0x6622)
PR_ROH_PRINCIPAL_NAME    = PT_UNICODE & "6625" ' PROP_TAG (PT_UNICODE, 0x6625)
PR_ROH_PROXY_AUTH_SCHEME = PT_LONG    & "6627" ' PROP_TAG (PT_LONG,    0x6627)

'' Flags that are used in PR_ROH_FLAGS
'' Connect to my Exchange mailbox by using HTTP.
Const ROHFLAGS_USE_ROH            = &h1
'' Connect by using SSL only.
Const ROHFLAGS_SSL_ONLY           = &h2
'' Mutually authenticate the session when connecting by using SSL.
Const ROHFLAGS_MUTUAL_AUTH        = &h4
'' On fast networks, connect by using HTTP first. Then, connect by using TCP/IP.
Const ROHFLAGS_HTTP_FIRST_ON_FAST = &h8
'' On slow networks, connect by using HTTP first. Then, connect by using TCP/IP.
Const ROHFLAGS_HTTP_FIRST_ON_SLOW = &h20

'' Values that are used in PR_ROH_PROXY_AUTH_SCHEME
'' Basic authentication
Const ROHAUTH_BASIC               = &h1
'' NTLM authentication
Const ROHAUTH_NTLM                = &h2

Const HKEY_CURRENT_USER = &h80000001

Set objReg = GetObject ("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")

objReg.EnumKey HKEY_CURRENT_USER, ProfilePath, arrSubKeys

For Each objSubKey in arrSubKeys

	strMAPIpropKey   = ProfilePath  & "\" & _
                           objSubKey    & "\" & _
                           ExchDetails

        strMAPIpropValue = PR_ROH_FLAGS

	e "Checking profile named " & objSubKey

	On Error Resume Next
	Err.Clear

	objReg.GetBinaryValue HKEY_CURRENT_USER, strMAPIpropKey, strMAPIpropValue, arrBinary

	On Error Goto 0

	If IsNull (arrBinary) Or Err Then
		e "...property value not found"
	Else
		'e "Values (" & UBound (arrBinary) & ")"
		'For i = 0 To UBound (arrBinary)
		'	e i & " " & arrBinary(i) & " " & Hex(arrBinary (i))
		'Next

		val = arrBinary (0)
		If (val and ROHFLAGS_HTTP_FIRST_ON_FAST) = ROHFLAGS_HTTP_FIRST_ON_FAST Then
			e "...On fast networks, connect using HTTP first --- IS SET"
		End If

		If (val and ROHFLAGS_HTTP_FIRST_ON_SLOW) = ROHFLAGS_HTTP_FIRST_ON_SLOW Then
			e "...On slow networks, connect using HTTP first --- IS SET"
		End If

		bitVal = ROHFLAGS_HTTP_FIRST_ON_SLOW Or ROHFLAGS_HTTP_FIRST_ON_FAST

		If (val and bitVal) = bitVal Then
			e "...Desired options are already set"
		Else
			e "...Updating"
			arrBinary(0) = arrBinary(0) Or bitVal
			result = objReg.SetBinaryValue (HKEY_CURRENT_USER, strMAPIpropKey, strMAPIpropValue, arrBinary)
			If result <> 0 Then
				e "...Could not update HTTP network value (" & result & ") !!!"
			Else
				e "...update complete"
			End If
		End If

	End If
Next

e "Done"

Set objReg = Nothing

Sub e(str)
	WScript.Echo str
End Sub

Until next time…

If there are things you would like to see written about, please let me know!

P.S. Thanks to Diane Poremsky and John Fullbright for assistance in creating this article.


Follow me on twitter: @EssentialExch

First Article in Red Gate’s Simple-Talk

Red Gate is a company based out of Cambridge in the UK. I ran into some of their team at TechEd last year. They are a great bunch of folks.

I’ve been doing tech. review for them on a number of articles since then, and I just had my first article published with them.

If you have a minute, take a look-see: Determining MS Exchange Disk Performance. It covers what’s important to look at in measuring Exchange disk performance and some tools to use.

My next article with them will be Outlook/Exchange related, and then I hope to do an article on calculating the anticipated performance of a RAID subsystem. Neat techie stuff. 🙂

Until next time…

As always, if there are items you would like me to talk about, please drop me a line and let me know!


Follow me on twitter: @EssentialExch