Microsoft

How To Set Up Enterprise Mode for Microsoft Edge

AKA How to force certain websites when opened in Edge, to instead open in Internet Explorer.

Microsoft Edge is undergoing a big change with the underlying platform being migrated to Chromium – things will change with that (along with a new Internet Explorer mode) but that doesn’t help right now.

Many companies have certain websites they need to use that either require Internet Explorer, or work best in Internet Explorer. This isn’t about what browser is ‘best’, but some solutions were designed with only Internet Explorer in use.

Getting users to use the right website in the right scenario can be a pain, and every user seems to have their own opinion on what browser they prefer to use. Microsoft Edge has a great solution for this – Enterprise Mode. There was also an Enterprise Mode in Internet Explorer that worked in a similar way too, where you could force certain sites to run as a certain version of IE for compatibility reasons.

This is quite easy to set up, but I’ve found the existing documentation rather confusing to follow and doesn’t give an end to end explanation – or documentation is rather outdated and was written when the feature first came out, with a lot of options changing since then.

Step 1Enterprise Mode Site List Manager

Download Enterprise Mode Site List Manager (schema v.2) and install it. This is the program you’ll use to manage the sites you want to force to use IE rather than Edge:

Enterprise Mode Site List Manager will start off blank. Click the ‘Add’ button on the bottom, type in the URL of the site you want to use (don’t worry about http or https if you want to catch both). You then tell it what to do with that URL – Open in IE, Edge, or do nothing. Since we’re opening everything in Edge except what we want in this list, open in IE11 is the option we want, and leave it at the default IE8 Enterprise Mode (or change this if you need a different compatibility mode).

There’s two parts to maintaining a list – Exporting/Importing lists, and Saving as XML:

Once you have a record to test, go to File > Export. This will save your details into an .emie2 file, and put that somewhere central and safe. The idea is that you’ll need to import that file list to make a change, then export again. If you don’t do this, you won’t have a way for others to get the list of sites and make changes by importing that file at a later date. It has in-built version control (this is important, more later), in the screenshot above you can see it’s version 5.

Then, you can save your URL to an XML file. This is what Edge will read when it launches. Either save this file centrally where everyone can read it (no write access required, just read), or copy it to everyone’s computer locally via GPO. Personally I’ve just put it in a central location.

Step 2 – Configure Group Policy or Intune

I’m using Group Policy, but the Microsoft Documentation mentions Intune is supported too – we’re only changing registry settings, so that makes sense.

Turning on Enterprise Mode can be done at either the Computer or User level, and is under > Policies > Administrative Templates > Windows Components > Microsoft Edge > Configure the Enterprise Mode Site List.

Enable this setting, and in the options enter the path of where your XML is – e.g. \\server\sharename\edge.xml – or C:\Data\edgesettings.xml. Although the Group Policy says URL, it’ll accept UNC paths or drives.

If you’ve used a Computer Configuration setting, gpupdate then reboot (or reboot twice). To tell if the setting has applied, check the value of the registry setting:

HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main\EnterpriseMode 

or 

HKEY_CURRENT_USER\SOFTWARE\Policies\Microsoft\MicrosoftEdge\Main\EnterpriseMode

SiteList = The path you entered in the Group Policy setting.

If you’re see that, great! Group Policy is working. One caveat if you have System Center Configuration Manager (ConfigMgr) – it can potentially use this setting also as per this technet thread which is exactly what I had. I was testing a user policy, but this was configured at both the user and computer levels so my user setting was being ignored. I’m not sure if this is still used, but worth being aware of.

Version control is also recorded in the registry. It lives under:

HKEY_CURRENT_USER\Software\Microsoft\MicrosoftEdge\Main\EnterpriseMode

CurrentVersion = 5

regardless of the SiteList being under Computer or User. There’s a few catches with this – first, it’ll only show up after Edge is launched, and you wait ~65 seconds. It’ll show the same version as what’s contained in the XML, which was the version we saw in Enterprise Mode Site List Manager.

If you have the ConfigMgr setting, or have ever had Enterprise Mode for Edge enabled in your environment, then the version might already exist and be higher than what you’ve tried to deploy. On my PC, I saw version 28000 something – that’s a lot of versions.

You’ll need to either delete that value for everyone to start back at 0, then after Edge is launched per user, it’ll update to whatever your XML file contains, or update the version in Enterprise Mode Site List Manager to a higher number than whatever’s out there in your environment.

To change the version in Enterprise Mode Site List Manager, on the computer with it installed navigate to

C:\Users\your username\AppData\Roaming\EMIESiteListManager\ – in that path should be a file called SiteList.xml.

That file should have the first line as <site-list version=”5″> or whatever the current version is, and you can just change that ‘5’ to whatever number you want. Open Enterprise Mode Site List Manager and you’ll see that updated version number, which will then get written +1 to the XML file next time you save it out.


That’s really it – it’s simple, but there are a few catches I ran into when testing. Once this is in place, if a user goes to a site that you’ve listed in the XML, a new window opens in IE and goes to that site instead. It’ll also support subsites, so you don’t need to sent traffic for an entire domain like adamfowlerit.com there, it could be adamfowlerit.com/news and only hits to that subdomain will be triggered.

There’s a few other Group Policy settings around this such as forcing all intranet sites to go to IE, you’ll need to work out what’s best for your environment.

Blocking Legacy Authentication – Conditional Access vs Authentication Policies

I’ve already written a post on why Legacy Authentication (Basic) is bad, and Modern Authentication is good. At the time of writing, Authentication Policies were the way to go to block Legacy Authentication methods. Of course, things change and there’s now a better* option to look at – Conditional Access.

I’ve also covered Conditional Access before, and it’s really hard to fault the solution. There are now Baseline policies deployed by default (still in preview though) to Azure AD tenants with recommended best practices:

Conditional Access Baseline Policies

One of these is for blocking legacy authentication – but I’m not going to recommend you turn this on (at least for starters, it’s good at the end when you know you have full modern authentication support), as it’s a tenant wide setting that has no exceptions if you need to allow legacy authentication for an account (unlike Require MFA for admins, which does allow exceptions).

Instead, you can create your own policy that does the same. This means you can gradually roll it out, and put exceptions in place until you either work around them, or live with them. If you have a requirement for an account that requires legacy auth, then you need to consider how else you’ll protect that account – can you use other Conditional Access policies to restrict it to a certain region/locations, certain apps, platforms etc – lock it down as much as you can, and make sure the account has a long unique password.

The single important setting to block legacy auth via a Conditional Access Policy is blocking access to ‘Other clients’ via Client apps:

Microsoft have a full guide on how to set this up on docs.microsoft.com.

So, why is this better than using Authentication Policies? Two main reasons:

If an account has their access or signin blocked due to an Authentication Policy, it’s not logged. You can look at the user in Azure AD and check the sign-ins, but you won’t see anything. However, if it blocked via Conditional Access, you’ll have a nice log entry showing you it was blocked:

Side note: Although in this example I was logging in from Australia, I was trying to connect to Exchange Online via PowerShell. That seems to often be detected as being in the US, so be careful with region blocking.

The other reason is that Authentication Policies can take up to 4 (!) hours to apply, although it’s often more like an hour. That is a long time to wait, and you just have to keep waiting and trying until it works – except if you did it wrong, you won’t know and you’ll keep waiting. Or, if you need to unblock access while rolling out, it’s a long time to roll back.

Authentication Policies do have their place though, they give more granular control over what you want to block or not – say you know you want to block POP3 access company wide, but not IMAP – that’s possible in there, but not via Conditional Access.

Unless you have a good reason to use Authentication Policies, just use Conditional Access (and assuming you have Azure AD Premium P1 or P2 licensing to actually let you use Conditional Access, and if you are using Azure AD you should be on that licensing anyway). It’ll make your life easier!

How To Check What Files Are In Use On A Remote Windows Computer

This one had me stumped for a while, and I even asked on Twitter with a large amount of replies (thanks everyone who did!) but none that I could get to work, or that weren’t overly complicated requiring the compiling of code.

It’s easy locally to find out what files are open, and here’s a great article covering several free ways: https://www.winhelponline.com/blog/find-process-locked-file-openfiles-utility/

None of those worked remotely for me in a Windows 10 environment – but I thought Handle from the SysInternals Suite would be the best bet. Running locally, it did exactly what I wanted – a giant list of every file open, and say what process had it open (like WinWord.exe).

Using PSExec with Handle however, causes it to forever wait for something. On the remote PC, it definitely launches handle.exe and handle64.exe, but they have no activity. I thought it might be the EULA prompt getting stuck somewhere, but there’s a registry setting that will autoaccept that prompt, and putting that in place didn’t help (but I did check locally and it was skipping the EULA agree prompt. Thanks to this blog post explaining the reg key required https://peter.hahndorf.eu/blog/post/2010/03/07/WorkAroundSysinternalsLicensePopups which was:

reg.exe ADD HKCU\Software\Sysinternals /v EulaAccepted /t REG_DWORD /d 1 /f

I added this to the remote machine under both the user logged on to the remote device, and the user I was connecting as, with no luck.

After a bunch of Googling and trying solutions, I ended up finding this thread on stackoverflow. One of the answers with 0 votes (which can be easily overlooked) was a PowerShell script, invoking the command remotely, from a user called A.D – thank you A.D!

I’ve barely modified it for my purposes, but if this helps you please go vote his post up on stackoverflow (I did but don’t have enough rep for it to show):

$computerName = 'computername'
 $stringtoCheck = 'test' # String you want to search for, can be blank by removing text between '' quotes
 $pathtoHandle = 'c:\temp\handle.exe' #location of handle.exe on the remote server.
 Invoke-command -ComputerName $computerName -Scriptblock {
     param(
     [string]$handles,
     [string]$stringToCheck
     )
      "$handles /accepteula $stringToCheck" | Invoke-Expression 
     } -ArgumentList $pathtoHandle,$stringtoCheck

The script requires handle.exe to be on the remote computer under C:\Temp, and that of course you have admin rights to the remote PC with the account this script is being run. Beyond that, it’ll show back all open files that match the variable set in $stringtocheck across any of the results – it could be the path, the process that has the file open etc.

Why would you want to do this remotely at all? You might be troubleshooting something to do with open files and not want to interrupt the user. You might have a reason to see what files the user has open, or maybe it’s a locked PC and the user left.

Hope this helps others as it was a much harder task to accomplish than I assumed.

Converting a user mailbox to shared in Exchange Online Hybrid

This is a useful process a lot of companies follow when an employee departs: Instead of deleting the mailbox, or continue to leave the mailbox in place and pay for licensing, it’s possible to instead set it as a shared mailbox and keep the data there for free.

There are some catches to this, such as the maximum amount of data is 50gb. You also can’t delete the user’s account, but it can be disabled and moved.

Setting the mailbox from User to Shared in Exchange Online is easy (from docs.microsoft.com):

In the admin center, go to the Users > Active users page.

Choose the user whose mailbox you want to convert.

In the right pane, choose Mail. Under More actions, choose Convert to shared mailbox.

…but there’s two tricks I’ve found when doing this in a hybrid environment. First, docs.microsoft.com says to update the status of the mailbox for Exchange On-Premises:

If this shared mailbox is in a hybrid environment, we strongly recommend (almost require!) that you move the user mailbox back to on-premises, convert the user mailbox to a shared mailbox, and then move the shared mailbox back to the cloud.

That’s a tedious process to do just to make it shared. As they point out, you can change some AD attributes locally to get around this, but there’s still some scenarios where it might get set back as a user, have no license, and end up getting deleted.

This other article on support.microsoft.com however, mentions the main way of getting around this: by setting the account’s msExchRemoteRecipientType and msExchRemoteRecipientTypeDetails attributes to the corresponding values that would match it’s state in Exchange Online:

Set-ADUser -Identity ((Get-Recipient PrimarySmtpAddress).samaccountname) -Replace @{msExchRemoteRecipientType=100;msExchRecipientTypeDetails=34359738368}

This 1 line command will set the attributes correctly, you can check via PowerShell or the Exchange Management Console to see that the mailbox will now show as ‘Shared’.

The other problem I’ve seen is if a mailbox is Unified Messaging (UM) Enabled, and converted to Shared. You’d think that it would either just lose it’s UM status, or let you configure the UM settings after the fact; but neither are correct. If it’s holding onto an extension number as part of UM, even in it’s Shared Mailbox state it will continue to hold it, and block any other account from using the extension in the future.

To get around this issue, the account will need to both be changed back to a user account from shared, and given a license that supports UM. If you try to disable UM on the account with either of these requirements, you’ll see an error like these:

User testuser@domain.com is already disabled for Unified Messaging.

License validation error: the action ‘Disable-UMMailbox’, ‘Identity’, can’t be performed on the user ‘Test User’ with license ‘BPOS_S_Standard’.

With all of the above, changing a user to a departed mailbox in a hybrid environment with Unified Messaging should be:

  1. Disable Unified Messaging on the user
  2. Set the attributes of the AD account as shared
  3. Set the Exchange Online mailbox as shared

It should work well if you do things in the right order, but it’s easy to not be aware of this and get things into a mess.

There’s also the scenario where you might create an account, give it Office 365 licenses and have a mailbox automatically created before you did it on-premises, or used Exchange On-premises to create the mailbox remotely.

You can fix that by using this script from Adaxes (doesn’t need their software!) which will tell on-premises Exchange about the mailbox and create the record.

I’ve come across another blog that goes into some of this http://jetzemellema.blogspot.com/2016/02/convert-user-mailbox-to-shared-in.html but I haven’t needed to change the license status, but it’s worth mentioning in case there’s a scenario you hit where you do.

Force Multi-Factor Authentication Registration in Azure Active Directory

If you’ve gone down the path of Azure Active Directory (Azure AD), then I dare say you’re not at the end. It’s a long but rewarding path, with new features constantly being added to enhance a critical service in the Microsoft offerings.

It’s also likely you didn’t start with Mutli-Factor Authentication (MFA) in place and ready to go. Maybe you did and well done! For the rest of us though, we slowly move into these systems while turning more options on.

Just enabling MFA with Conditional Access is great, but getting all users to actually register for MFA https://aka.ms/mfasetup can be a challenge. If you’re fortunate enough to have Azure AD Premium P2 licensing, you can use a MFA registration policy to do a nicely managed rollout and force people on. Those without P2 however, have an option that’s a bit hidden, not as well known and slightly scary:

Require users to register when signing in?


Under the question mark: Designates whether unregistered users are prompted to register their own authentication information when they sign in for the first time. If set to “No,” administrators must manually specify the necessary password reset authentication information in the properties for each user in this directory, or instruct users to go to the registration portal URL directly.

The description for this option is a bit misleading, it actually means that they’ll be prompted the NEXT time they log in, rather than the first time.

This option is found under Azure Active Directory > Password reset > Registration, and is off by default.

Turning this option on is a company wide setting and from my testing, worked pretty much immediately. As soon as someone who hadn’t signed up for MFA logged onto office.com, they were prompted to go through the MFA registration process. There’s no way to point this at certain users or test it, you just have that one little switch to turn it on for every single account in your tenant.

For someone who had signed up for MFA, they were asked to confirm the details entered previously.

I’d recommend letting your staff know before this option is toggled, but at least it can easily be turned off again if you run into any issues.

Update 2nd May:

After publishing this, Sean Flahie on Twitter mentioned his experience if Azure Self-Service Password Reset (SSPR) wasn’t enabled for users, and enabling the combined experience – both of which I have in place already. If you’re having any issues then please look into both of these.