Method not allowed

Method not allowed

Whilst trying to perform DAG tasks in an Exchange 2010 environment (suspending replication, moving an active database copy), I was getting some warnings (in yellow) as follows:

WARNING: The cmdlet extension agent with the index 0 has thrown an exception in OnComplete(). The exception is:
System.Net.WebException: The request failed with HTTP status 405: Method Not Allowed.
at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
at Microsoft.Exchange.SoapWebClient.CustomSoapHttpClientProtocol.<>c__DisplayClass4.b__3()
at Microsoft.Exchange.SoapWebClient.HttpAuthenticator.NetworkServiceHttpAuthenticator.AuthenticateAndExecute[T](SoapHttpClientProtocol client, AuthenticateAndExecuteHandler`1 handler)
at Microsoft.Exchange.SoapWebClient.SoapHttpClientAuthenticator.AuthenticateAndExecute[T](SoapHttpClientProtocolclient, AuthenticateAndExecuteHandler`1 handler)
at Microsoft.Exchange.SoapWebClient.EWS.ExchangeServiceBinding.FindFolder(FindFolderType FindFolder1)
at Microsoft.Exchange.ProvisioningAgent.MailboxLoggerFactory.EwsMailer.GetAdminAuditLogsFolder(ADUser adUser)
at Microsoft.Exchange.ProvisioningAgent.MailboxLoggerFactory.EwsMailer..ctor(OrganizationId organizationId, ADUser adUser, ExchangePrincipal principal)
at Microsoft.Exchange.ProvisioningAgent.MailboxLoggerFactory.Create(OrganizationId organizationId, ADUser mailbox, ExchangePrincipal principal)
at Microsoft.Exchange.ProvisioningAgent.AdminLogAgentClassFactory.ConfigWrapper.get_MailboxLogger()
at Microsoft.Exchange.ProvisioningAgent.AdminLogProvisioningHandler.OnComplete(Boolean succeeded, Exception e)
at Microsoft.Exchange.Provisioning.ProvisioningLayer.OnComplete(Task task, Boolean succeeded, Exception exception)


They were just warnings, but I still needed to get to the bottom of them as they indicate a problem.

The crux of this is the “The request failed with HTTP status 405: Method Not Allowed” – implying to me an authentication problem. I was suspecting that the hardware load balancers were at fault. I understood that the action that I was doing would have result in Autodiscover being updated (or attempted updating). I examined the authentication types on the Autodiscover virtual directory and tested direct connectivity by tricking my client with a hosts file entry. This ruled out the load balancers as I still got the error. Nothing was amiss with the vdirs or authentication. This was also not limited to one CAS server, thus reducing the likelihood of it being an IIS that simply needed recycling. I had deliberately set the external url on the Autodiscover virtual directory when I installed Exchange 2010 into the environment so that the existing clients didn’t get any impact from an untested service. That testing has been successfully completed, so it is now safe to expose clients to Autodiscover and that is what fixed it.

In my case the above warning message actually meant The external url of the Autodiscover Virtual Directory is blank”. Obvious really, eh? I populated the external url for all the new Exchange 2010 CAS servers and that’s the end of the warnings.


Relay Connectors & multi-valued properties

I’ve been working with Receive connectors, specifically relay connectors.

101 Relay Connectors – A basic Receive Connector can be used to allow hosts to relay internally. By adding an AD Permission, you can allow hosts to relay externally. So why not create two relay connectors?

New-ReceiveConnector -Server -RemoteIPRanges 1.2.3.4 -Name "Allowed to Relay Internally HTS_Server" -AuthMechanism Tls, BasicAuth -PermissionGroups AnonymousUsers -MaxMessageSize 20MB -Bindings 0.0.0.0:25,:::25

New-ReceiveConnector -Server -RemoteIPRanges 6.7.8.9 -Name "Allowed to Relay Externally HTS_Server" -AuthMechanism Tls, BasicAuth -PermissionGroups AnonymousUsers -MaxMessageSize 20MB -Bindings 0.0.0.0:25,:::25

Get-ReceiveConnector | ?{$_.name -like "Allowed to Relay Externally*"} | Add-ADPermission -User "NT AUTHORITY\ANONYMOUS LOGON" -ExtendedRights "ms-Exch-SMTP-Accept-Any-Recipient"


So now we have Relay Connectors, but adding IP Addresses to them is not such a simple task. When you use Set-ReceiveConnector –RemoteIPRanges the existing values get overwritten.

I tried to apply the instruction given in article http://technet.microsoft.com/en-gb/library/bb684908(v=exchg.150).aspx as follows:

Set-ReceiveConnector <RelayConnector> –RemoteIPRanges @{Add=”1.2.3.4”}

It should have worked. But it didn’t :-(

So I tried this instead: http://exchangepedia.com/2007/02/how-to-update-multi-valued-attributes-in-powershell.html as follows:

$var= Get-ReceiveConnector <RelayConnector>; $var.RemoteIPRanges +=”1.2.3.4”; $var | Set-ReceiveConnector "RelayConnector"

And even:

$var= Get-ReceiveConnector <RelayConnector>; Get-Content .\IPs.txt | foreach {$rc.RemoteIPRanges += "$_"}; $var | Set-ReceiveConnector

Still no joy :-(

I don't want to have to do this in EMC. I may have a load of addresses to add. And the trouble with listing them is that the buffer size of the Exchange Management Shell causes the field to be truncated. Even after using Out-String. So what’s the quickest and easiest way to append IP addresses to a receive connector?
By using the ‘View Exchange Management Shell Command Log’ (http://technet.microsoft.com/en-gb/library/ee332355.aspx). If you add one IP address (e.g. 1.2.3.4) then you’ll see the command that was run to add it, listing all the existing values. Copy, paste, massage in notepad and use in EMS to add the additional IP addresses or ranges. E.g.:

Set-ReceiveConnector -Identity 'SERVER01\Allowed to Relay Internally SERVER01' -RemoteIPRanges '1.2.3.4', '2.3.4.5'

And then to list multiple IP addresses or address ranges in a Receive Connector's RemoteIPRanges property:

(Get-ReceiveConnector "RelayConnector").RemoteIPRanges | ft Lowerbound,Upperbound,RangeFormat -AutoSize


Powershell remoting

I always configure my new Exchange servers for remote management and Powershell remoting but also run commands on each server. Sometimes these are commands that I want to run in a disconnected session but the default for MaxShellsPerUser is set to 5, which can cause issues with running remote scripts. The value is by design as per this article (http://blogs.msdn.com/b/powershell/archive/2010/05/03/configuring-wsman-limits.aspx) but if you know what you're doing (and you should do if you're trying to overcome this problem) then raising the value to 25 is not harmful. Unfortunately I couldn't do this remotely (by design to prevent malicious reconfiguration), but it's a simple one liner on each server:

$l = Get-Location; cd WSMan:\localhost\Shell; Set-Item .\MaxShellsPerUser 25; dir; Set-Location $l

If I break that down - assigning the current location to a variable just allows us to return to the same place afterwards; change to WSMan path; modify the value; show some output; return to the original location

Now I can run remote commands without exceeding the MaxShells limit, such as this one for restarting the Exchange Transport service on multiple servers:

$s = new-pssession -computername SERVER1, SERVER2, SERVER3
invoke-command -session $s {$h = Restart-Service MSExchangeTransport}
exit-pssession


More info on Powershell remoting can be found at:
http://technet.microsoft.com/en-us/library/dd819505.aspx