O365: Testing Problems With RpcProxy for Outlook Anywhere Migrations

NOTE: This post – drafted, composed, written, and published by me – originally appeared on https://blogs.technet.microsoft.com/johnbai and is potentially (c) Microsoft.

Often times, it may be necessary to test the RpcProxy URL to verify connectivity to your servers. There are various reasons for doing this but the primary is to verify if the connectivity problem isn’t limited to a problem with Exchange in O365.

RpcProxy is a compound URL, meaning it comprises different parts to make the whole. Let’s use this example URL and I’ll break down what I mean:


So, the easiest one is the ‘mail.contoso.com’ as it’s the vanity name for external access to the Exchange environment. We follow that with the rpcproxy path in IIS, ‘/rpc/rpcproxy.dll’. We use a delimiter ‘?’ between the vanity name and the server and this is to pass the server we want to hit in the backend (in 2007, this will be your node name). Then, we have the server name ‘MailboxServer.contoso.com’, followed by one of the Outlook Anywhere ports: 6001, 6002, or 6004.

How do we test it? Easy! Use your favorite web browser and browse to the target destination. IIS should require you to authenticate (use your on-premises credentials you use for the migration) and you should get a blank page.

How do we know it fails? Well, the first sign would be a HTTP 400 error. If you have ISA or a TMG, you might get 503 or 500 errors; you may also get “The server denied the specified Uniform Resource Locator (URL). Contact the server administrator.” The key here is: is the error reproducible from other sources and what is the error returned, if any?

Using PowerShell and .NET to Construct a DirectorySearcher

NOTE: This post – drafted, composed, written, and published by me – originally appeared on https://blogs.technet.microsoft.com/johnbai and is potentially (c) Microsoft.

PowerShell and .NET are very interoperable and can help to save time, when you’re performing generic, every day tasks. For example, let’s say that I want to create a Date-Time value that’s thirty minutes ago and one for right now, we can do this in one fell swoop in Exchange Management Shell (read: PowerShell):

v2: Get-MessageTrackingLog -Start [System.DateTime]::Now.AddMinutes(-30) -End [System.DateTime]::Now

v3: Get-MessageTrackingLog -Start ([System.DateTime]::Now).AddMinutes(-30) -End ([System.DateTime]::Now)

As you can see, the syntax changes slightly but the methods are the same because they derive from the same .NET class.

Below, I demonstrate constructing a DirectorySearcher object for a specific case. The final script is published on OneScript, here, but I wanted to demonstrate that we can use PowerShell + .NET to solve some complex problems in a rather easy way.


In rare cases, removal of an Exchange Server from the forest doesn’t go according to plan and, without Exchange Management Shell (EMS), finding servers via Active Directory might be a bit of a pain-point. Enter DirectorySearcher.

Here is an example, finding Exchange 2013 mailbox servers in the forest:

$colMBX = @()
$CurrentDomain = [System.DirectoryServices.ActiveDirectory.Domain]::GetComputerDomain()
$ForestName = $CurrentDomain.Forest.Name
$ForestDC = $ForestName.Replace(“.”,”,DC=”)
$ForestLDAP = [ADSI]”LDAP://CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=$ForestDC”
$orgName = $ForestLDAP.psbase.children | where {$_.objectClass -eq ‘msExchOrganizationContainer’}
$Path = “LDAP://CN=Servers,CN=Exchange Administrative Group (FYDIBOHF23SPDLT),CN=Administrative Groups,CN=” + $orgName.Name + “,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=” + $ForestDC
$Searcher = New-Object System.DirectoryServices.DirectorySearcher
$Searcher.Filter = ‘(&(&(&(objectCategory=msExchExchangeServer)(msExchCurrentServerRoles:1.2.840.113556.1.4.803:=54)(serialNumber=*15*))))’
$Searcher.PageSize = 10000
$Searcher.SearchScope = “OneLevel”
$Searcher.PropertiesToLoad.Add(“Name”) | Out-Null
$Searcher.SearchRoot = $Path
$ServerResult = $Searcher.FindAll()
foreach ($result in $ServerResult)
       $colMBX += $result.Properties.name[0]

You’ll notice that in the filter we’re using the numeric value ‘1.2.840.113556.1.4.803’ between the attribute and the value we’re seeking. This OID is an Extensible Matching Rule for the bitwise operator AND, which may also be referred to as ‘LDAP_MATCHING_RULE_BIT_AND‘. It is not required for use in your filter but does follow RFC convention.

In Exchange 2013, for Mailbox servers we can use the value ’54’ to search and for CAS servers we can use the value ‘16385’.

To explain the values, we can demonstrate via table:

Server role Role value
Mailbox role 2
Client Access role (CAS) 4
Unified Messaging role 16
Hub Transport role 32

The Mailbox role now has the previous roles in one server, so 2 + 4 + 16 + 32 = 54.

You can read more on PowerShell + DirectorySearcher here: http://technet.microsoft.com/en-us/library/ff730967.aspx