Where are those DNS requests coming from?

A customer recently asked me which networks or IP addresses Microsoft make DNS requests from. This may seem like an unusual question, but they were deploying geo load balancers for AD FS, and wanted to know where they should expect to see DNS traffic originating from.

Microsoft doesn’t (currently) publish a list of these networks / IP addresses, which makes sense, as DNS resolvers are normally entirely public or entirely private. However, this customer has a security requirement to restrict access wherever possible, so I duly investigated.

I created an Ubuntu virtual machine (using DigitalOcean), made sure port 53 was open, started a tcpdump and then made Microsoft connect. To do this, I created a subdomain of my domain, delegated DNS for it to my ‘DNS server’, and told Exchange Online this was a migration endpoint, thus prompting a DNS query from Microsoft.

The requests came pouring in…

Microsoft DNS Queries

In total, Microsoft made 233 DNS requests against my pretend DNS server, from 21 different IP addresses. I imagine the volume was because my DNS server wasn’t really a DNS server, and you can see this in the traffic patterns; the same servers made multiple requests because they didn’t get a response on their first attempt.

I looked at a few of the addresses the requests came from and found that they were registered to Microsoft (as one might expect), they didn’t have reverse DNS entries, and, as far as I could see, none were listed on the Office 365 URLs and IP address ranges page.

Personally, I don’t have a problem with this, and the customer in question is happy to open up port 53 to the world and lock down access to the endpoint itself rather than the DNS servers, but I think it’s still interesting to see some of the inner workings of the Microsoft cloud and the scale at which Microsoft does something as mundane as a DNS query.

DNS-over-HTTPS in PowerShell


Have you ever needed to perform an external DNS lookup from inside a LAN, and found yourself unable to do so because of a corporate policy or firewall rule? You have a few options, including using one of a number of free websites that will perform the query on your behalf.

These are fine if you just need to do the occasional lookup, but if you need to perform the lookup programmatically, or across a number of hostnames, you’re out of luck.

I recently discovered that Google offers a DNS-over-HTTPS API that (as the name might suggest) lets you perform DNS lookups using a HTTPS API. It’s still in preview at the moment, but it seems to work well, and I imagine it will later be offered under the same terms as Google’s other free DNS services. I’ve written a PowerShell wrapper for it that has a similar input to the native ‘Resolve-DnsName’ cmdlet.

I’ve put the function, Resolve-GoogleDnsName, on GitHub.

Google lets you send arbitrary data to try and mask the request (which won’t be necessary for most people), so I’ve include a pseudo-random string generator of sorts that gets a bunch of GUIDs and includes them in the request.


Exchange Hybrid Licenses

For a while, Microsoft has offered customers a ‘free’ license of Exchange Server 2010 or Exchange Server 2013 for use in a hybrid deployment. These are special licenses, and can only be used on servers exclusively used for hybrid, i.e. for mail flow, migration and availability sharing. They can’t host user mailboxes, or be used for any other purpose.

A common misconception was that these licenses were free for anybody running hybrid, including those customers who already had Exchange Server 2010. This wasn’t true, and Microsoft explicitly stated that you were only eligible if you ‘currently [did] not have a licensed Exchange 2013 or Exchange 2010 SP3 server in your on-premises organization‘. The purpose of the hybrid license was to enable those customers running Exchange Server 2003 or Exchange Server 2007 to configure hybrid, as those versions predate Office 365. In fact, KB2939261 is still online, and still contains that condition.

Fortunately, Microsoft has recently updated the Exchange hybrid key distribution wizard, and these conditions no longer apply. You can now get a free hybrid key, no matter what version of Exchange you currently have in your organisation, or even if you don’t have Exchange. Microsoft has also updated the wizard to issue keys for Exchange Server 2016. Now, the only conditions on the license are as below.

You can use the Hybrid Edition of Exchange Server 2016 only to enable hybrid functionality between Exchange Online users and on-premises Exchange 2010 or 2013 users. You cannot use the hybrid server to host on-premises mailboxes, to enable calendar sharing with other organizations (except for calendar sharing with Exchange Online users), to perform email filtering, or any other functionality that is not required for hybrid deployment.

See  for full details and to check your eligibility.

Get Lync Version Using PowerShell

I recently had to do some discover work to determine what version of Lync / Skype for Business was being used, based solely on a user’s SIP domain. It turns out, if lyncdiscover and the dialin pages are published to the internet, this is a pretty straightforward thing to do in PowerShell by parsing the response. Helpfully, Microsoft include the version in the title of the page! I’ve wrapped this up in a function called ‘Get-LyncVersion’, see below.

Obviously, this will only show what version is presented to the world, and it’s entirely possible that more than one version is in use, but in most cases it’s going to be correct. It’ll also detect the presence of Skype for Business Online by searching for ‘lync.com’ in the URL.

Continue reading »

Office 365 & CheckPoint Firewalls

One of the biggest challenges for some organisations when moving to Office 365 is the need to open up firewalls to allow the service to communicate with their on-premise environment. A common task is opening up port 25 to allow communication from the Exchange Online Protection (EOP) IP addresses. The list is long, and adding these by hand is tiresome.

I was recently working with a customer who uses CheckPoint firewalls, and rather than add in the subnets manually, and then add them to a group, I thought I’d see if I could automate it.

The following script gets the list of EOP IP addresses and prints out a script to create ‘network objects’ for each of the subnets, and then groups them into a ‘network object group’ called ‘EOPNetworks’. Once you’ve got the group, it’s trivial to create a rule that allows all the addresses through, and you can use this to configure NAT rules too if required.

Continue reading »

EOP IP Addresses in PowerShell

I’ve written a PowerShell function to get the latest list of Exchange Online Protection IP addresses and return them in a usable format. Just copy the function below into your script and run. I’ve deliberately excluded the region-specific networks as these overlap the global networks listed at the top of the page.

Credit to Mark Hatton for the IPv4 regular expression.

CollectOverMetrics.ps1 Problems

If you’ve ever troubleshooted database failovers on Exchange, you may have tried to use the CollectOverMetrics.ps1 script that comes with Exchange. However, if you’ve tried running it after the 12th of the month and your Exchange Server uses the DD/MM/YYYY date format, you may be faced with a sea of red text and a very empty looking report.

This is because the script needs to covert date strings to date objects, and uses a method that expects MM/DD/YYYY. Fortunately, this is quite easy to fix.

  1. Take a copy of CollectOverMetrics.ps1, CollectOverMetrics-help.xml and CollectOverMetrics.strings.psd1 from the $exscripts folder.
  2. Edit CollectOverMetrics.ps1 as follows:



These should be on lines 978 and 979.

Fast PowerShell Filtering

I often need to work with large datasets in PowerShell (such as CSV files), and a common task I need to perform is a case insensitive wildcard search, something like this:

Import-CSV .UserList.csv | Where-Object {$_.OrganizationalUnit -like "*europe*"}

However, beyond a few thousand rows, this is painfully slow. The above query on my 3.5 million row CSV took a staggering 268 seconds. To speed things up, I tried using the ‘-match’ filter instead of ‘-like’:-

Import-CSV .UserList.csv | Where-Object {$_.OrganizationalUnit -match "europe"}

This sped things up slightly, and took just 241 seconds which is better, but not by much. To speed things up even more, I have written a PowerShell filter specifically for this purpose, and it’s much, much quicker:

Import-CSV .UserList.csv | WhereLike OrganizationalUnit europe

This takes just 28 seconds to complete the same query.

Continue reading »

Exchange 2013 Mapi.Submit.Monitor

If you are running Exchange 2013 on-premise, and you monitor the health of your Exchange Servers using Managed Availability or SCOM, you may have noticed that the ‘Mapi.Submit.Monitor’ is unhealthy:

I have seen this in a number of different Exchange 2013 environments and, as far as I can see, there is no obvious cause for it. Delving into the crimson channel reveals an error that suggests something is seriously wrong:

Mailbox Transport Submission – the verification that the probe messages were successfully submitted within 5 minutes to HUB has failed.
This could indicate that the mailbox submissions are taking too long or not progressing at all.
SequenceNumber: 635761113388494348

Error: MapiSubmitLAMProbe finished with CheckPreviousMail failure.
FailureContext: MapiSubmitLAMProbe finished with CheckPreviousMail failure.
ExecutionContext: MapiSubmitLAMProbe started. This performs – 1. Submits a new message to Store 2. Checks results from previous Send Mail operation. Sequence # = 635761113388494348. First Run? = False. Previous mail submission to store was successful. Results – # of previous results: 0. Could Not Find stages that ran. Previous SendMail failure – Mail submitted to Store during the previous run never reached SendAsCheck.
This may indicate a latency from Store to Submission Service. Investigating. Found lower SA latency. Indicates an issue in Submission service.
Investigate. In SendMail – NotificationID=00000040-0000-0000-0000-00003d872e0c Sending mail. SendMail finished. MapiSubmitLAMProbe finished with CheckPreviousMail failure.
CheckPreviousRunMail exception details:
Current SendMail exception details:

MailWasSentInLastRun (0(no)/1(yes)): 1
CheckMailSuccess(0(no)/1(yes)): 0
SendMailSuccess(0(no)/1(yes)/2(no-noMDBs)/3(no-noActiveMDBs)/4(no-ignorableException)): 1

PreviousMailLatencies: <fb8e5616813c416ea85802c6e3b0310f@EXCH01.example.com>,,2015-08-25T22:40:47.838Z;LSRV=EXCH01.example.com:TOTAL-SUB=0.406|SA=0.093|MTSSDA=0.003|MTSSDC=0.001|SMSC=0.023|SMS=0.141|MTSSDMO=0.246|MTSSDPL=0.003|MTSSDSS=0.004|MTSSD=0.269|MTSS=0.269;;<595e16a12e684d00a61c1dc95df3fc66@EXCH01.example.com>,,2015-08-25T22:35:47.684Z;LSRV=EXCH01.example.com:TOTAL-SUB=0.500|SA=0.078|MTSSDA=0.007|MTSSDC=0.001|SMSC=0.026|SMS=0.230|MTSSDMO=0.340|MTSSDPL=0.003|MTSSDSS=0.004|MTSSD=0.370|MTSS=0.370;;<7d7382e22f5d491a95d615ee3dba8990@EXCH01.example.com>,,2015-08-25T22:30:47.530Z;LSRV=EXCH01.example.com:TOTAL-SUB=0.406|SA=0.046|MTSSDA=0.003|MTSSDC=0.001|SMSC=0.051|SMS=0.154|MTSSDMO=0.288|MTSSDPL=0.003|MTSSDSS=0.004|MTSSD=0.310|MTSS=0.310;;

(The following are applicable if the mail was actually sent)
MailSentAt: 8/25/2015 10:45:47 PM
TimeInSendingToStore: 15.6222
Sent Mail Result Details:
ItemEntryId:0 0 0 0 4 2D 41 13 BD 79 21 45 82 AB AA C9 48 59 50 31 7 0 66 97 10 CC 30 C4 97 4C 97 65 69 5 75 16 AB FB 0 0 0 0 1 B 0 0 66 97 10 CC 30 C4 97 4C 97 65 69 5 75 16 AB FB 0 0 10 52 54 0 0 0 )
Properties of Sending mail
Body and MessageClass:MessageClass:IPM.Note.MapiSubmitLAMProbe;MessageBody:This is a Probe Mapi message that’s Submitted from Store to Mailbox transport Submission service to Hub transport service;
DoNotDeliver, DropMessageInHub and DeleteAfterSent:DoNotDeliver:True;DropMessageInHub:True;DeleteAfterSubmit:True;)
Probe Exception: ‘System.ApplicationException: MapiSubmitLAMProbe finished with CheckPreviousMail failure.
at Microsoft.Forefront.Monitoring.ActiveMonitoring.Transport.Probes.MapiSubmitLAMProbe.PerformProbeFinalAction(Boolean potentialForAlertBasedOnPreviousRun, Boolean potentialForAlertBasedOnCurrentRun, Exception previousRunVerificationException, Exception currentRunException, DateTime timeMessageSentToStore)
at Microsoft.Forefront.Monitoring.ActiveMonitoring.Transport.Probes.MapiSubmitLAMProbe.DoWorkInternal(CancellationToken cancellationToken)
at Microsoft.Forefront.Monitoring.ActiveMonitoring.Transport.Probes.MapiSubmitLAMProbe.DoWork(CancellationToken cancellationToken)
at Microsoft.Office.Datacenter.WorkerTaskFramework.WorkItem.Execute(CancellationToken joinedToken)
at Microsoft.Office.Datacenter.WorkerTaskFramework.WorkItem.<>c__DisplayClass2.<StartExecuting>b__0()
at System.Threading.Tasks.Task.Execute()’
Probe Result Name: ‘Mapi.Submit.Probe’
Probe Result Type: ‘Failed’
Monitor Total Value: ‘0’
Monitor Total Sample Count: ’12’
Monitor Total Failed Count: ’12’
Monitor Poisoned Count: ‘0’
Monitor First Alert Observed Time: ‘8/25/2015 3:15:39 PM’

After a lengthy escalation to Microsoft Premier Support, I can confirm that this is a known issue and can be safely ignored:

It is a known issue.

We have seen multiple cases on it , currently there is no fix on it. We can only suppress it, or ignore it until the fix is available there is no ETA on when the fix will be available.

To configure a Global Monitoring Override for this, run the following. This will override the monitor on all servers that are running Exchange 2013 CU9:

Hopefully this will save someone a lot of head scratching!

Full Access Control for Users

If you want to give another user access to your mailbox on Exchange, you have two options: contact your administrator and request they grant Full Access permissions, or use the built-in delegation wizard in Outlook.

Having to log a service request to get Full Access permissions is a pain, both for you and for your helpdesk. Using the delegation wizard has it’s own limitations, particularly if you want to grant access to a non-default folder, i.e. a subfolder under your inbox.

If you set up delegation before creating a subfolder, then your delegate can see the folder, but if the folder already exists before you set up delegation, they can’t. You can manually set permissions on a per-folder basis, but this is time consuming.

Wouldn’t it be great if you could bridge the gap and allow users to grant proper Full Access permissions to their delegates, without having to involve an Exchange administrator? Thankfully, with Exchange’s Role Based Access Control (RBAC), it’s possible to grant a user just enough administrative permission to be able to control Full Access (and indeed Send As) permissions through the Exchange Administration Centre (EAC). In this blog post, I’ll show you how it’s done.

Continue reading »