Exchange Connections – ONLINE!

I speak at a number of conferences, usually including those put on by Penton Media. Their conferences are called Connections, and a conference is held each fall and spring.

During last fall’s conference, a bunch of folks got together and convinced Penton to make the conferences available online, for viewing on the Internet. Thus was born Connections Online! This is designed to help those people who cannot convince management (or afford it themselves) to pay for travel and a conference ticket. The online presentations are available at a very reasonable price.

I submitted two sessions for Exchange Connections Online: VSS Backup and Exchange, and Decoding E-mail Message Headers.

Lots of other names in the Exchange speaking circuit submitted sessions too: David Elfassy, Ilse van Criekinge, Jim McBee, Ken St. Cyr, Martin Tuip, Glen Scales, and others. You can see the entire Exchange line up here.

Of course, there are many other Connections tracks available too: SharePoint, Windows, SQL, ASP.NET, etc. Visit the main website for Connections Online!

Until next time…

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


Follow me on twitter: @EssentialExch

Microsoft Exchange Server 2010 Release Candidate

After a wait of almost 24 hours – the download is available.

Yesterday, the Microsoft Exchange team announced the immediate availability of the Exchange Server 2010 Release Candidate with this posting. However…. there was a complication… it wasn’t available!

As of a few minutes ago (1630 EST) the situation was resolved and you can now download the RC here.

A couple of quick notes about this release:

  • This is the Enterprise edition of Exchange Server
  • To use the DAG functionality, you’ll need the Enterprise Edition of Windows Server
  • Windows Server 2008 SP2 and Windows Server 2008 R2 are both supported – but no version of Server 2003 or earlier version of Server 2008
  • You will be able to upgrade to the released version of Exchange Server when it is released, but you CANNOT upgrade from Enterprise RC to Standard RTM
  • You cannot install DAG (which uses Windows Failover Clustering) and NLB on the same server (this is a Windows restriction, not an Exchange restriction)
  • This is an RC – that is, it is feature complete but may still have bugs.

There is a huge amount of additional functionality over Exchange Server 2007 – however, much of it is only available in the Exchange Management Shell. Since this release is feature complete, I don’t expect that to change prior to RTM.

Until next time…

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


Follow me on twitter: @EssentialExch

Microsoft Exchange Server 2010 Release Candidate

After a wait of almost 24 hours – the download is available.

Yesterday, the Microsoft Exchange team announced the immediate availability of the Exchange Server 2010 Release Candidate with this posting. However…. there was a complication… it wasn’t available!

As of a few minutes ago (1630 EST) the situation was resolved and you can now download the RC here.

A couple of quick notes about this release:

  • This is the Enterprise edition of Exchange Server
  • To use the DAG functionality, you’ll need the Enterprise Edition of Windows Server
  • Windows Server 2008 SP2 and Windows Server 2008 R2 are both supported – but no version of Server 2003 or earlier version of Server 2008
  • You will be able to upgrade to the released version of Exchange Server when it is released, but you CANNOT upgrade from Enterprise RC to Standard RTM
  • You cannot install DAG (which uses Windows Failover Clustering) and NLB on the same server (this is a Windows restriction, not an Exchange restriction)
  • This is an RC – that is, it is feature complete but may still have bugs.

There is a huge amount of additional functionality over Exchange Server 2007 – however, much of it is only available in the Exchange Management Shell. Since this release is feature complete, I don’t expect that to change prior to RTM.

Until next time…

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


Follow me on twitter: @EssentialExch

Mailbox Permissions: Pulling Back the Curtain…

Let’s talk about mailbox permissions. People often get a little confused between store-level mailbox permissions and Active Directory-level mailbox permissions. They are similar but not the same. For clarity it may help for us to look at them all.

Note: this post is written specifically against Exchange Server 2007. For Exchange Server 2010, storage groups disappear – mailbox stores acquire storage group attributes, they are promoted to equal status (you could see this coming, as a number of features in Exchange Server 2007 only worked when you had a single mailbox store per storage group). So, the contents of this post apply equally to Exchange Server 2010 – just where-ever you see “storage group”, replace that with “mailbox store”.

Mailbox permissions include: FullAccess, SendAs, ExternalAccount, DeleteItem, ReadPermission, ChangePermission, and ChangeOwner. This list does not include “Send on Behalf”. That’s because a user can set “Send on Behalf” for another user by defining the other user as a delegate and that’s handled separately from mailbox permissions.

Relevant Active Directory permissions include: FullControl, SendAs, ReceiveAs, Delete, and ViewInfoStoreStatus. Three of these (SendAs, ReceiveAs, and ViewInfoStoreStatus) are so-called “extended rights”, which means they are handled somewhat differently than standard access rights.

The AD permission ViewInfoStoreStatus allows a specific user or group to do just that – view the status of an information store. It doesn’t map to anything at the mailbox level. I don’t believe that it is used in Exchange 2007 and above. It had applicability in the Exchange 2000 and Exchange 2003 timeframe when administration of Exchange was handled at the “Administrative Group” level, and ViewInfoStoreStatus was assigned to an administrative group for the administrators of that administrative group (and set to inherit down through all the servers and stores in that group).

The AD permission FullControl includes Delete, SendAs, and ReceiveAs at the AD level. At the mailbox level this maps to FullAccess and SendAs.

The AD permission ReceiveAs maps to FullAccess at the mailbox level. Note that this does not include SendAs or ExternalAccount permissions. There is no way (even though some Microsoft documentation states otherwise) to provide read-only access to a mailbox via permissions.

The AD permission SendAs maps to SendAs at the mailbox level. Note that while it is possible to set Send-As on the mailbox itself, without having it set in AD, you will not be able actually Send-As using Outlook – it depends on Send-As being set within AD.

The AD permission Delete maps to DeleteItem at the mailbox level.

The store permission FullAccess includes all mailbox permissions except SendAs and ExternalAccount.

Setting the AD permission does not cause the mailbox permission(s) to be set (AD has no direct knowledge of Exchange). One must presume that the information store service is smart enough to check both. I have no idea of the official precedence map of AD permissions vs. store permissions. However, behavior indicates that AD permissions are evaluated first, and if they produce a “pass” then the store permissions are evaluated to get the final result (similar to the “share” vs. “NTFS” precedence rules).

The AD permissions can be set on a storage group or a mailbox store, and apply to all mailboxes in that storage group or mailbox store (if set for inheritance). There is no mechanism to do that within the mailbox store itself (that is, there is no cmdlet for Add-MailboxDatabasePermission or Add-StorageGroupPermission, nor do I believe that a store has a concept of a security hierarchy above the mailbox level). Also, while you can set SendAs at the storage group or mailbox store level, this just means that you can impersonate the storage group or mailbox store – it does not mean that you can Send-As for all accounts in that storage group or mailbox store. That permission must be set on a per-mailbox basis.

There is a good whitepaper for understanding store and AD permissions written against Exchange 2000 and Exchange 2003. It is still at microsoft.com/downloads : Working with Store Permissions in Microsoft Exchange 2000 Server and Exchange Server 2003. However, it is a little dated and there are a couple of errors in the document. The basics are still good, but Exchange 2007 reintroduced the idea of setting actual permissions on the mailbox (in 2000 and 2003, you could set mailbox permissions only before the mailbox was created, everything else was set against the AD user object). Exclusive of the impact of Role Based Access Control (commonly referred to as RBAC), I believe that Exchange Server 2010 continues to follow the Exchange Server 2007 rules.

While we have not discussed them here, note that the store-level permissions available to mailboxes are the same permissions available to public folders (excepting only ExternalAccount). And, with the exception of SendAs and ExternalAccount, these are the same permissions available to subfolders within a mailbox and a public folder.

Implementation note:

From a technical perspective, the AD attributes actually represent Access Control Entries set within the nTSecurityDescriptor object assigned to a user object within Active Directory.

For more information on Access Control Lists, Access Control Entries, and the nTSecurityDescriptor object, see Displaying Security on Active Directory, Exchange, and Registry Objects and Windows Permissions – Access Control Lists.

Until next time…

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

P.S. Thanks to Ross Smith, IV of Microsoft for clarifying a couple of points contained in this article.


Follow me on twitter: @EssentialExch

Mailbox Permissions: Pulling Back the Curtain…

<p>Let’s talk about mailbox permissions. People often get a little confused between store-level mailbox permissions and Active Directory-level mailbox permissions. They are similar but not the same. For clarity it may help for us to look at them all.</p>
<blockquote>
<p>Note: this post is written specifically against Exchange Server 2007. For Exchange Server 2010, storage groups disappear – mailbox stores acquire storage group attributes, they are promoted to equal status (you could see this coming, as a number of features in Exchange Server 2007 only worked when you had a single mailbox store per storage group). So, the contents of this post apply equally to Exchange Server 2010 – just where-ever you see “storage group”, replace that with “mailbox store”.</p></blockquote>
<p>Mailbox permissions include: FullAccess, SendAs, ExternalAccount, DeleteItem, ReadPermission, ChangePermission, and ChangeOwner. This list does not include “Send on Behalf”. That’s because a user can set “Send on Behalf” for another user by defining the other user as a delegate and that’s handled separately from mailbox permissions.</p>
<p>Relevant Active Directory permissions include: FullControl, SendAs, ReceiveAs, Delete, and ViewInfoStoreStatus. Three of these (SendAs, ReceiveAs, and ViewInfoStoreStatus) are so-called “extended rights”, which means they are handled somewhat differently than standard access rights.</p>
<p>The AD permission ViewInfoStoreStatus allows a specific user or group to do just that – view the status of an information store. It doesn’t map to anything at the mailbox level. I don’t believe that it is used in Exchange 2007 and above. It had applicability in the Exchange 2000 and Exchange 2003 timeframe when administration of Exchange was handled at the “Administrative Group” level, and ViewInfoStoreStatus was assigned to an administrative group for the administrators of that administrative group (and set to inherit down through all the servers and stores in that group).</p>
<p>The AD permission FullControl includes Delete, SendAs, and ReceiveAs at the AD level. At the mailbox level this maps to FullAccess and SendAs.</p>
<p>The AD permission ReceiveAs maps to FullAccess at the mailbox level. Note that this does <strong>not</strong> include SendAs or ExternalAccount permissions. There is no way (even though some Microsoft documentation states otherwise) to provide read-only access to a mailbox via permissions.</p>
<p>The AD permission SendAs maps to SendAs at the mailbox level. Note that while it is possible to set Send-As on the mailbox itself, without having it set in AD, you will not be able actually Send-As using Outlook – it depends on Send-As being set within AD.</p>
<p>The AD permission Delete maps to DeleteItem at the mailbox level.</p>
<p>The store permission FullAccess includes all mailbox permissions except SendAs and ExternalAccount.</p>
<p>Setting the AD permission does not cause the mailbox permission(s) to be set (AD has no direct knowledge of Exchange). One must presume that the information store service is smart enough to check both. I have no idea of the official precedence map of AD permissions vs. store permissions. However, behavior indicates that AD permissions are evaluated first, and if they produce a “pass” then the store permissions are evaluated to get the final result (similar to the “share” vs. “NTFS” precedence rules).</p>
<p>The AD permissions can be set on a storage group or a mailbox store, and apply to all mailboxes in that storage group or mailbox store (if set for inheritance). There is no mechanism to do that within the mailbox store itself (that is, there is no cmdlet for Add-MailboxDatabasePermission or Add-StorageGroupPermission, nor do I believe that a store has a concept of a security hierarchy above the mailbox level). Also, while you can set SendAs at the storage group or mailbox store level, this just means that you can impersonate the storage group or mailbox store – it does not mean that you can Send-As for all accounts in that storage group or mailbox store. That permission must be set on a per-mailbox basis.</p>
<p>There is a good whitepaper for understanding store and AD permissions written against Exchange 2000 and Exchange 2003. It is still at microsoft.com/downloads : <a href=”http://www.microsoft.com/downloads/details.aspx?familyid=2ae266f0-16b7-40d7-94d9-c8be0e968a57&amp;displaylang=en” target=”_blank”>Working with Store Permissions in Microsoft Exchange 2000 Server and Exchange Server 2003</a>. However, it is a little dated and there are a couple of errors in the document. The basics are still good, but Exchange 2007  reintroduced the idea of setting actual permissions on the mailbox (in 2000 and 2003, you could set mailbox permissions only before the mailbox was created, everything else was set against the AD user object). Exclusive of the impact of Role Based Access Control (commonly referred to as RBAC), I believe that Exchange Server 2010 continues to follow the Exchange Server 2007 rules.</p>
<p>While we have not discussed them here, note that the store-level permissions available to mailboxes are the same permissions available to public folders (excepting only ExternalAccount). And, with the exception of SendAs and ExternalAccount, these are the same permissions available to subfolders within a mailbox and a public folder.</p>
<p><strong>Implementation note:</strong></p>
<p>From a technical perspective, the AD attributes actually represent Access Control Entries set within the nTSecurityDescriptor object assigned to a user object within Active Directory.</p>
<p>For more information on Access Control Lists, Access Control Entries, and the nTSecurityDescriptor object, see <a href=”http://theessentialexchange.com/blogs/michael/archive/2007/11/13/displaying-security-on-active-directory-exchange-and-registry-objects.aspx” target=”_blank”>Displaying Security on Active Directory, Exchange, and Registry Objects</a> and <a href=”http://theessentialexchange.com/blogs/michael/archive/2007/11/13/windows-permissions-access-control-lists.aspx” target=”_blank”>Windows Permissions – Access Control Lists</a>.</p>
<p>Until next time…</p>
<p>If there are things you would like to see written about, please let me know!</p>
<p>P.S. Thanks to Ross Smith, IV of Microsoft for clarifying a couple of points contained in this article.</p>
<hr><p>Follow me on twitter: @EssentialExch</p>

TEC’2009 Berlin (The Experts Conference)

TEC’2009 is coming up soon… I’ll be there and I hope you will be too. TEC is a place to get acquainted with some of the top folks in Active DIrectory, ILM/FIM, and Exchange.

Here is what Gil Kirkpatrick, the founder of the conference had to say:

 

I just wanted to remind all the list denizens that I will again be hosting The Experts Conference Europe this September 14-16 in Berlin, Germany.
TEC is comprised to two conferences this year. TEC/Identity and Access features speakers from Microsoft (Alex Weinert, Markus Vilcinskas, and Tomasz Onyszko for ILM/FIM 2010, Dean Wells, Nathan Muggli, and Brett Shirley for DS, and Matt Steele for Geneva), as well as notable MVPs Guido Grillenmeier, Jorge de Almeida-Pinto, and Brian Desmond.
TEC/Exchange includes Ross Smith IV, Greg Taylor, and Brett Shirley from Microsoft, as well as Exchange MVPs Ilse van Criekinge and Michael B. Smith.
You can see the entire TEC agenda at http://www.tec2009.com, and if you have any questions, contact me at gil.kirkpatrick@quest.com.
It would be great to see some of the activedir crowd at TEC this year. If you need to come up with a justification, well, listening to brettsh explain the innards of ESE is worth the price of admission right there.
-gil
I hope to see you there!

 


Follow me on twitter: @EssentialExch

TEC’2009 Berlin (The Experts Conference)

TEC’2009 is coming up soon… I’ll be there and I hope you will be too. TEC is a place to get acquainted with some of the top folks in Active DIrectory, ILM/FIM, and Exchange.

Here is what Gil Kirkpatrick, the founder of the conference had to say:

I just wanted to remind all the list denizens that I will again be hosting The Experts Conference Europe this September 14-16 in Berlin, Germany.
TEC is comprised to two conferences this year. TEC/Identity and Access features speakers from Microsoft (Alex Weinert, Markus Vilcinskas, and Tomasz Onyszko for ILM/FIM 2010, Dean Wells, Nathan Muggli, and Brett Shirley for DS, and Matt Steele for Geneva), as well as notable MVPs Guido Grillenmeier, Jorge de Almeida-Pinto, and Brian Desmond.
TEC/Exchange includes Ross Smith IV, Greg Taylor, and Brett Shirley from Microsoft, as well as Exchange MVPs Ilse van Criekinge and Michael B. Smith.
You can see the entire TEC agenda at http://www.tec2009.com, and if you have any questions, contact me atgil.kirkpatrick@quest.com.
It would be great to see some of the activedir crowd at TEC this year. If you need to come up with a justification, well, listening to brettsh explain the innards of ESE is worth the price of admission right there.
-gil
I hope to see you there!


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

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

msExchTargetBridgeheadServersDN and msExchSourceBridgeheadServersDN Errors with Routing Group Connectors

I’m working with a client this week on migrating them from Exchange Server 2003 to Exchange Server 2007.

Their Exchange 2003 environment is a weird one – a A/A/A/P/P cluster. That’s right – Active/Active/Active/Passive/Passive. Whoever sold them that solution made some serious money! 🙂

I’m moving them to a more standard solution – dual front end servers (CAS + HT) and a CCR backend for the mailboxes. Obviously, we are going to have coexistence for some period of time – there are thousands of mailboxes involved.

One of the standard steps in a co-existence scenario is to create a inter-server-version (InterOp) routing group connector (RGC) which allows the Exchange 2003 environment to communicate (i.e., transfer email) with the Exchange 2007 environment.

Today I finished setting up the CAS+HT servers and the CCR servers and began to set up the InterOp RGC. I used the same syntax I’ve used with dozens of other migrations:

New-RoutingGroupConnector -name Interop-RGC -SourceTransportServers server1, server2, server3 -TargetTransportServers ExchCas1, ExchCas2 -BiDirectional $true -PublicFolderReferralsEnabled $true

And… crap. It bombs.

WTF?!?!?

New-RoutingGroupConnector : Active Directory operation failed on dc3.example.com. This error is not retriable. Additional information: The name reference is invalid.
This may be caused by replication latency between Active Directory domain controllers.
Active directory response: 000020B5: AtrErr: DSID-03152392, #1:
0: 000020B5: DSID-03152392, problem 1005 (CONSTRAINT_ATT_TYPE), data 0, Att 315c30e2 (msExchTargetBridgeheadServersDN)
At line:1 char:26
+ new-routinggroupconnector <<<< -domaincontroller dc3.example.com -identity "Exchange Administrative Group (FYDIBOHF23SPDLT)\Exchange Routing Group (DWBGZMFD01QNBJR)\InterOp-RGC" -sourcetransportservers server1, server2, server3 -targettransportservers ExchCas1, ExchCas2 -BiDirectional $true -PublicFolderReferralsEnabled $true

Well, it has nothing whatsoever to do with “replication latency between Active Directory domain controllers”. I spent far too long heading down that path before I started googling around to see what else might be on the “Interwebs” about this issue.

It turns out that Exchange 2003 assigns indexes to each SMTP Virtual Server on a computer. The New-RoutingGroupConnector command will only connect to SMTP Virtual Servers that have a index value of 1. Is this a bug? Absolutely. Has it been reported? Absolutely. Has it been fixed? Absolutely not. Note that the same error can occur with the attribute msExchangeSourceBridgeheadServersDN – depends on how you construct the cmdlet.

As of the Exchange 2010 beta, this issue still appears.

In a A/A/A/P/P cluster, the indexes for the SMTP Virtual Servers go 1, 2, 3. This means that you can only specify a single SMTP Virtual Server in the New-RoutingGroupConnector cmdlet, and you can only specify the SMTP Virtual Server for the Exchange Server that has the index of 1. This ALSO means that, for the InterOp-RGC to work, that the Exchange 2003 server with the index of 1 must be the routing group master!

Finding those things out cost me several hours of my life. I hope this blog post helps you avoid the same timesink I had!

Until next time…

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


Follow me on twitter: @EssentialExch