Exchange 2013 installation and annoying Outlook certificate Security Alert

I know, I know….why am I blabbering on about an Exchange version which is 3 years old?! The answer is because I still install it all the time, mainly for the purposes of Exchange Hybrid deployments. And this is probably old news to most of you, but if you didn’t know, Exchange 2013 can be particularly annoying when you first install it.

Once the install is completed, an SCP record is registered in Active Directory for your shiny new server (which still has all of its out of the box settings). If you faff around at all after the installation has completed, drinking tea and making merry at the water cooler, you will find that your users start moaning at you about the certificate errors they are receiving.

Outlook Certificate Error

This is because your new server has, without your consent, started merrily responding to Autodiscover and EWS requests made through Active Directory. This new server doesn’t have your public certificate installed, and also is using internal server names for it’s URLs.

What you need to do on Exchange 2013 to get around this is:

  • Install your trusted 3rd party SAN/wildcard certificate and assign it to the IIS service. Restart IIS
  • Configure, as a minimum, the Autodiscover, EWS and OAB Internal URLs to reflect your Exchange namespace
    • set-webservicesvirtualdirectory -identity ‘Servername\EWS (default web site)’ -internalurl ‘https://namespace.domain.com/ews/exchange.asmx’
    • set-oabvirtualdirectory -identity ‘Servername\OAB (default web site)’ -internalurl ‘https://namespace.domain.com/OAB’
    • set-clientaccessserver -server servername -autodiscoverserviceinternaluri ‘https://autodiscover.domain.com/autodiscover/autodiscover.xml’

This should mitigate the problem while you actually configure your server. Unfortunately it’s just part of the way Autodiscovery works, and personally I’d rather it was this way round, rather than having to remember to enable the SCP record at some point. Because knowing me, I’d forget.

You could also mitigate this problem by following the guidance on my blog post about Autodiscover optimisation and disabling SCP lookups temporarily for your users. If you are going to be using Hybrid in the future, this may be desirable anyway.

 

Azure Backup and Resource Manager Virtual Machines

Ask anybody in the Azure teams at Microsoft and they will tell you that Resource Manager is the future of Microsofts Azure strategy. And I agree; it’s much more versatile, robust, and finally gives us the ability to multitask rather than waiting for one task to complete before starting another. For all it’s benefits though, it is still an immature system. One big bugbear of mine is to do with changing Availability Sets once a VM is created, but that’s not what I wanted to write about today.

Microsoft recommend that all new services in Azure should be created using the Azure Resource Manager model. Which is all well and good, unless you want to back these servers up using Azure Backup. In which case you will have a problem.

I recently attempted to do this and was happily running through the guide provided by Microsoft entitled Deploy and manage backup to Azure for Windows Server/Windows Client using PowerShell. This article includes the following warning:

Warning: Azure Backup

I didn’t have a backup provider yet so I tried to run the command, only to be told that:

register-AzureProvider : The term 'register-AzureProvider' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. At line:1 char:1 + register-AzureProvider -ProviderNamespace Microsoft.DevTestLab + ~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (register-AzureProvider:String) [], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException

It seems that this cmdlet has been deprecated in Azure PowerShell v1.0.

Additionally, when looking into this error, I found the following tidbit of information on Microsofts Preparing your environment to back up Azure virtual machines page:

Backing up Azure Resource Manager-based (aka IaaS V2) virtual machines is not supported.

Bit of a showstopper eh? Luckily myself and my colleague simply wanted to schedule a backup of the ADFS database, so to workaround this we added a secondary Data disk to Azure and used Windows Server Backup to take a System State backup of the Primary ADFS server. For those planning a more extensive Azure Backup Strategy, you may need to rethink your use of v2 (Resource Manager) virtual machines.

As with all things Azure, things change all the time, and I’m sure Microsoft will add support for this feature very soon.

 

Exchange Online Public Folder Migration Fail

Today I have been migrating Public Folders (yuk!) from Exchange 2010 to Exchange Online, and have come across a slightly odd issue.

I had followed the lovely guide to Public Folder migrations provided by Microsoft here, however I could not complete my migration as the migration batch had completed with errors. The error I was receiving was as follows:

Error: MigrationMRSPermanentException: Error: There are 2 mail public folder‎(s)‎ in Active Directory that were not linked to any public folder during migration.

The Public Folders referenced in the error message were both Exchange system folders, so I wasn’t sure why it was bothering to try and synchronise them. Luckily the error message does give us a clue as to what to do;

You may also run "Set-MailPublicFolder -IgnoreMissingFolderLink:$true" for each AD object that is a legacy system folder and resume the migration

Being the silly person I am, I assumed that this command needed to be run against the legacy Public Folders On Premise, but apparently -IgnoreMissingFolderLink is not a parameter in Exchange 2010. What I actually needed to do, which is not obvious from the error message,  was to run this command in Exchange Online. I ended up using a catch all command, which looked like this:

Get-MailPublicFolder | Set-MailPublicFolder -IgnoreMissingFolderLink:$true

Once this was done, I stopped the migration batch, and then started it again. It then performed it’s initial sync and I was able to continue the migration!

 

Out-GridView Awesomeness

This post is more for me than anybody else but some may find it useful. I feel a bit late to this particular party, but I have recently encountered the awesomeness that is Out-Gridview, and have started using it to help me easily define variables. Here is an example. I want to display a list of all Mail Users and then select the objects which I would like to save to a variable. To do this I can run the following command:

$mailuser = Get-MailUser | Select Name,UserPrincipalName,RecipientType |  Out-GridView -Title "Select Mail User" -PassThru

This gives me a selection box, containing the columns I specified, which I can then use to select the mail users I need for my variable. I can also search and define additional criteria to filter by. As I want to select multiple mail users, I can just Ctrl select as many users as I’d like and then click OK. Obviously IRL there would not be a gigantic black box covering your view, I am just protecting the innocent here!

out-gridview

If I now use $mailuser to show the results of my variable, I can see that the users I selected are there and I can manipulate them as I see fit. How I’ve lived my life before Out-Gridview I don’t know, but now I’ve found it I’m sure to cherish it for all time!

ADFS & Multi Factor Authentication – Force MFA for browser based access to Office 365

Azure MFA is a great concept in itself, especially when applied to Office 365 using ADFS, but quite often there is a need for granular control over when MFA is actually applied. There are GUI options for enabling MFA just for extranet requests, but this poses several problems:

  1. Issues with Autodiscover requests – these are proxied from Office 365 and thus always route via the ADFS Proxy servers. This means that all Autodiscover requests, no matter where the client is located, appear to originate from the internet, which poses a problem when applying MFA to only be enforced for Extranet requests, as Outlook clients will be prompted for MFA even when inside the Intranet.
  2. Mobile Applications – These will likely always come from Extranet locations. It is undesirable, and in some cases unsupported, for these applications to use MFA whenever they are opened.
  3. Skype for Business client – It is not desired to require MFA when Skype for Business is opened from the Extranet.

One thing worth mentioning straight off the bat is that using the Azure MFA server with ADFS requires the ADFS Proxies either use the WAP role in Server 2012 R2 or a 3rd party proxy which can add the claim “http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy” to show whether the connection is coming from the Extranet or not.

If you need more granular control than Extranet or Intranet (taking into account the considerations above), you need to use the Azure MFA server option to integrate MFA with ADFS. This provides the ability to great custom rules for your relying parties. There is a great guide on installation of this service here: https://azure.microsoft.com/en-gb/documentation/articles/multi-factor-authentication-get-started-adfs-w2k12/#securing-windows-server-2012-r2-ad-fs-with-azure-multi-factor-authentication-server

In addition to the MFA Server configuration itself, a custom ADFS claim needs to configured to force MFA if certain conditions are present. This can be very fiddly and currently there are not any GUI based tools to achieve this, so PowerShell is your friend!

For my example, I wanted to force MFA if the request comes from a browser on the extranet. This ensures that Outlook, the Skype for Business client and mobile applications never require MFA, but any access from browsers outside of the local network are MFA secured. The claim looks like this:

c:[Type == "http://schemas.microsoft.com/ws/2012/01/insidecorporatenetwork", Value == "false"] && 

c1:[Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-endpoint-absolute-path", Value =~ "(/adfs/ls)|(/adfs/oauth2)"] 

=> issue(Type = "http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", Value = "http://schemas.microsoft.com/claims/multipleauthn");

This rule was applied using the below command. First, the above rule was set as the $mfarule variable.

$mfarule='c:[Type == "http://schemas.microsoft.com/ws/2012/01/insidecorporatenetwork", Value == "false"] && c1:[Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-endpoint-absolute-path", Value =~ "(/adfs/ls)|(/adfs/oauth2)"] => issue(Type = "http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", Value = "http://schemas.microsoft.com/claims/multipleauthn");'

Then the Office 365 Relying Party Trust was set as a variable.

$rpt = Get-AdfsRelyingPartyTrust –Name "Microsoft Office 365 Identity Platform"

And then the Authentication Rule was applied to the Relying Party!

Set-AdfsRelyingPartyTrust –TargetRelyingParty $rpt –AdditionalAuthenticationRules $mfarule

Before this was placed into production, a similar claim rule was applied which limited MFA to only a particular group of users. The claim for this is shown below and the group is specified using the ObjectSID. This is useful for testing the rule out on a subset of users:

c:[Type == "http://schemas.microsoft.com/ws/2012/01/insidecorporatenetwork", Value == "false"] && c1:[Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-endpoint-absolute-path", Value =~ "(/adfs/ls)|(/adfs/oauth2)"] && c2:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid", Value == "S-1-5-21-3388933763-2387696048-3050347461-86618"] => issue(Type = "http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationmethod", Value = "http://schemas.microsoft.com/claims/multipleauthn");

This gave us the settings we needed for compliance, and figuring out the claim rules was complicated but quite fun. I hear that all this functionality will be moving into a GUI based system in Server 2016 so that’ll be nice.

Anyway, if anybody has any particular claim types they would like for particular situations, let me know and we can try and put something together

P.S. Huge thanks to Mark Vale and his article on the same subject, it helped me find the light in a very dark tunnel!

http://skype4b.uk/2015/06/12/adfs-multifactor-authentication-not-good-for-office-365/

Office 365 Hybrid – On Premise Room Mailboxes not available in OWA

I came across an issue today wherein a user whose mailbox was hosted on Office 365 attempted to use OWA to book a meeting On Premise, and was told that there were no rooms available. The list simply didn’t contain any rooms. The Room Mailboxes were synchronised to Office 365 using the AADSync tool, however OWA knew nothing about them. When using Outlook, the Rooms were shown correctly, so this was just an issue with OWA, not with Room Mailboxes per se.

After a little digging, I found the following KB article: https://support.microsoft.com/en-us/kb/2904381 which explains that a Room List should be created and synchronised to Office 365 to get this working in OWA.

However the PowerShell cmdlet in the KB article fell a little short as I had over 100 Rooms to add into the Distribution Group. This was the PowerShell I ended up using:

$members=Get-Mailbox -RecipientTypeDetails RoomMailbox
New-DistributionGroup -Name "RoomList" -RoomList -Members $Members

I then moved the newly created Distribution Group into the correct OU and performed a Directory Sync. The RoomList showed up instantly, but it took 5-10 minutes for it to become populated. Once this was all done, the Rooms were available!

RoomOWA

Script to change Exchange internal URLs

All Exchange consultants will have been through this situation at least once now; a customer is using a split namespace in their Exchange environment with a .local name internally, and due to the new requirements for purchasing SAN certificates, they can no longer purchase certificates with a .local name on them. One way of remedying this is to change all the Exchange internal URLs to use the public name, and add in an internal DNS zone and record to point the public name at the Exchange environment.

Changing the URLs for multiple virtual directories and servers can be a pain. There are many scripts like this out there on the internet, but I frankenstein’ed this one to fit the needs I had. I wanted it to prompt for the server name, public FQDN and autodiscover FQDN and then change the directories on that particular server to reflect the names I had entered. I also love simplicity, so I wanted the most simple script possible. If you wanted to change this to do the external URL’s, then just do a find and replace internal with external! This script will work on Exchange 2010 and 2013.

Also, if you are using a wildcard certificate, be sure to run the below command to force the name match, otherwise you may get certificate errors on your clients!

Set-OutlookProvider -identity EXPR -certprincipalname msstd:*.domain.com

Here is the script I use:

#get variables
write-host "Set Exchange 2010 Internal URLS" –Foregroundcolor Yellow
$urlpath = Read-Host "Type CAS Array FQDN starting with https://"
$autodpath = Read-Hosts "Type Autodiscover FQDN starting with https://"
$CASserver = Read-Host "Type internal server FQDN"
#change urls for all internal directories
Set-AutodiscoverVirtualDirectory -Identity "$CASserver\Autodiscover (default web site)" –internalurl “$autodpath/autodiscover/autodiscover.xml”
Set-ClientAccessServer –Identity "$CASserver" –AutodiscoverServiceInternalUri “$autodpath/autodiscover/autodiscover.xml”
Set-webservicesvirtualdirectory –Identity "$CASserver\EWS (default web site)" –internalurl “$urlpath/ews/exchange.asmx”
Set-oabvirtualdirectory –Identity "$CASserver\OAB (default web site)" –internalurl “$urlpath/oab”
Set-owavirtualdirectory –Identity "$CASserver\OWA (default web site)" –internalurl “$urlpath/owa”
Set-ecpvirtualdirectory –Identity "$CASserver\ECP (default web site)" –internalurl “$urlpath/ecp”
Set-ActiveSyncVirtualDirectory -Identity "$CASserver\Microsoft-Server-ActiveSync (default web site)" -InternalUrl "$urlpath/Microsoft-Server-ActiveSync"
#get commands to to doublecheck the config
get-AutodiscoverVirtualDirectory -Identity "$CASserver\Autodiscover (default web site)" | ft identity,internalurl
get-ClientAccessServer –Identity "$CASserver" | ft identity,AutodiscoverServiceInternalUri
get-webservicesvirtualdirectory "$CASserver\EWS (default web site)" | ft identity,internalurl
get-oabvirtualdirectory "$CASserver\OAB (default web site)" | ft identity,internalurl
get-owavirtualdirectory "$CASserver\OWA (default web site)" | ft identity,internalurl
get-ecpvirtualdirectory "$CASserver\ECP (default web site)" | ft identity,internalurl
get-ActiveSyncVirtualDirectory "$CASserver\Microsoft-Server-ActiveSync (default web site)" | ft identity,internalurl

Restrict OneDrive for Business synchronisation to domain joined machines only

Edit: This can now be done in a GUI by using the OneDrive Admin Centre at admin.onedrive.com. It also allows Mac clients by default now.

A quick preface to this post; making the changes listed below will stop all Mac clients from being able to sync their OneDrive, and will not stop mobile devices from connecting to OneDrive using the app. It also doesn’t stop the downloading or uploading of files from the web access of OneDrive. It’s sole purpose is to limit the functionality of the Windows OneDrive for Business sync client!

Firstly you need to find out the GUID for the Active Directory domain which you want to be able to sync OneDrive for Business from. To do this, log onto a Domain Controller and run the Active Directory Module for PowerShell, or run a normal PowerShell window and run

import-module ActiveDirectory

in order to get the correct cmdlets imported. Get a list of your domains by running

(Get-ADForest).Domains

And then use this command to get a list of GUIDs which will be in the same order as your domain list

$domains = (Get-ADForest).Domains; foreach($d in $domains) {Get-ADDomain -Identity $d | Select ObjectGuid}

From this you should be able to work out the correct GUID for your Active Directory domain name. Copy and paste that sucker into notepad. Now head on over to a SharePoint Online PowerShell session using the SharePoint Online Powershell module and Connect-SPOService and run

Set-SPOTenantSyncClientRestriction  -Enable -DomainGuids "b45b7d67-e68b-430e-bb76-2a31948b3221”

Make sure you replace the GUID here with the GUID you copied and pasted earlier and this setting will lock down your OneDrive for Business synchronisation to client which have the same domain GUID. If you want to enter more than one GUID, separate them with commas.

Hope this helps and sorry if it’s a bit of a haphazard blog post, it was written in a bit of a hurry!

Disable Clutter feature for all users in Office 365

DisableClutter

Now I’m not one to advocate turning features off in Office 365, but sometimes when deploying Office 365 for a customer, there is simply too much change at one time. And if there is one thing that users hate, it is too much change!

Many customers I work with will choose to disable Skype for Business or OneDrive during the initial migration of email into the cloud. They can then plan the roll out of these services at a later date, and educate users on how to make the best use of it. This is much more preferable to just throwing a load of new functionality at users and expecting them to just start using it all with no training. After all, adoption of new technology starts with giving users the knowledge and power to be able to use the tools effectively!

And on that subject is a feature which has baffled and confused some users. This is called ‘Clutter’, and it uses machine learning to help organise the email which you don’t look at regularly, but may not want to delete (for example, that weekly newsletter from exchangeserverpro.com). This mail is automatically moved into your Clutter folder, clearing up your inbox so that it contains the email you need to know about now!

Email which is automatically moved out of your inbox does have the ability to freak users out if they aren’t expecting it, so you may want to disable this at first and then enable once you can communicate it’s purpose and usefulness to the business. To do this, you will need to make use of the mighty PowerShell!

Log yourself into Exchange Online PowerShell and use the following commands depending on your needs:

To disable Clutter for a single user:

Set-Clutter -Identity user@domain.com -Enable $false

To disable Clutter for all users:

Get-Mailbox | Set-Clutter -Enable $false

This command has a long list of outputs. If you want to hide the outputs, just add > $null to the end of the command, like this:

Get-Mailbox | Set-Clutter -Enable $false > $null

You can check to see if a mailbox has Clutter enabled by running:

Get-Clutter -Identity MailboxID | fl

And look for the IsEnabled parameter, which should be set to False!

So in summary, feel free to turn it off, but whatever you do, make sure you turn it on again as Clutter is definitely a useful tool to have in your email armoury!

Azure Active Directory Sync – AAD Connect Disaster Recovery and High Availability

I just wanted to write and tell you all about a fantastic new feature built into the AAD Connect tool. It’s name is ‘Staging Mode’ and it has a dual purpose; a) it allows you to have a server which is essentially on standby, and b) it can be used just as it’s name suggests, in a kind of test mode where you can see what is being imported before it all gets sent off to Azure AD.

In real life it would be utilised thus:

Customer A has a functional installation of AAD Sync / AAD Connect which is synchronising objects and attributes between Azure Active Directory and the On Premise Active Directory. They then build an AAD Connect server in their DR datacentre (or wherever they fancy), and during the initial configuration, enable ‘Staging Mode’. Apart from this setting, they configure it just like their existing, live AAD Sync / AAD Connect server. They even leave the scheduled task enabled and running. All of a sudden, DR strikes, and the live AAD Sync / AAD Connect server goes offline forevermore, cast into the computer graveyard in the sky. Rather than restore the server from backup, they simply log into their second AAD Connect server and disable ‘Staging Mode’. This server then starts synchronising with Azure Active Directory in earnest, without having to miss a beat.

What Staging Mode does is very simple. It acts just like a functional AAD Connect installation, except for the fact that it exports nothing to Azure Active Directory or your on premise Active Directory. It also does not perform any password sync or password write-back functions. The metaverse is fully populated and ready to start exporting data, giving you the easiest possible way to have a server on standby. Unfortunately there is no replication between your two synchronisation servers, so any configuration changes need to be replicated manually, but this is another step to making AAD Connect fully HA, which is becoming much more desirable as Azure Active Directory gains traction.

AADConnect Staging Mode