DMARC Quarantine Issues

Posted on Leave a commentPosted in dkim, dmarc, EOP, exchange, exchange online, Exchange Online Protection, Exchange Server, spf, spoof

I saw the following error with a client the other day when sending emails from the client to any of the Virgin Media owned consumer ISP email addresses (virginmedia.com, ntlworld.com, blueyonder.com etc.)

mx3.mnd.ukmail.iss.as9143.net gave this error:
vLkg1v00o2hp5bc01Lkg9w DMARC validation failed with result 3.00:quarantine

In the above, the server name (…as9143.net) might change as will the value before the error, but either DMARC validation failed with result 3.00:quarantine or 4.00:reject is the end of the error message.

We resolved this error by shorting the DMARC record of the sending organization. Before we made the change we had a DMARC record of 204 characters. We cannot find a reference online to the maximum length of a DMARC record, though we could successfully add a record of this length to Route 53 DNS provided by AWS, though a record of 277 characters was not allowed in AWS. Other references online to domain character length seem to imply that 255 characters is the max, but not specifically for DMARC.

So, shortening the DMARC record to remove two of the three email addresses in each of the RUA and RUF values was the fix that we needed. This change was done for two reasons, first the above error occurred only with emails to Virgin Media and sometimes an NDR would be received and other times the NDR would fail, but the original email never made it through and secondly the two removed email addresses where not actively being checked for DMARC status messages anyway and so there is no harm in the removal of them from the DMARC record anyway!

The original DMARC record we had this issue with looked like this (xxx.xxxxx representing the client domain):

v=DMARC1; p=quarantine; fo=1;rua=mailto:admin@xxx.xxxxx,mailto:dmarc-rua@dmarc.service.gov.uk,mailto:dmarc@xxx.xxxxx;ruf=mailto:admin@xxx.xxxxx,mailto:dmarc-ruf@dmarc.service.gov.uk,mailto:dmarc@xxx.xxxxx;

Then we changed the record to the following to resolve it:

v=DMARC1; p=quarantine; fo=1;rua=mailto:dmarc-rua@dmarc.service.gov.uk;ruf=mailto:dmarc-ruf@dmarc.service.gov.uk;

Reducing the length of the record resulted in DMARC analytics and forensic email not going to mailboxes at the client (one of whom those mailboxes did not exist anyway) and only going to the UK government DMARC policy checking service, but most importantly for a client that has a requirement to respond to citizen’s emails (and whom could easily be using Virgin Media email addresses) we resolved the issue.

XOORG, Edge and Exchange 2010 Hybrid

Posted on Leave a commentPosted in 2010, Edge, EOP, exchange, exchange online, Exchange Online Protection, Exchange Server, Office 365

So you have found yourself in the position of moving to Exchange Online from a legacy version of Exchange Server, namely Exchange 2010. You are planning to move everyone, or mostly everyone to Exchange Online and directory synchronization plays a major part (can it play a minor part?) in your plans. So you have made the option to go hybrid mode when you discover that there are manual steps to making Exchange 2010 mail flow to Exchange Online work if you have Exchange Edge Servers in use.

So, what do you do. You look online and find a number of references to setting up XOORG, but nothing about what that is and nothing about what you really need to do. And this you found this article!

So, how do you configure Exchange Server 2010 with Edge Servers, so that you can have hybrid mode to Exchange Online.

Why You Need These Steps

So you ran the hybrid wizard, and it completed (eventually if you have a large number of users) and you start your testing only to find that emails never arrive in Office 365 whilst your MX record is still pointing on-premises. After a while you start to get NDR’s for your test emails saying “#554 5.4.6 Hop count exceeded – possible mail loop” and when you look at the diagnostic information for administrators at the bottom of the NDR you see that your email goes between the hub transport servers and the edge servers and back to the hub transport servers etc. and about three or so hours after sending it, with the various timeouts involved, the email NDR arrives and the message is not sent.

The problem is that the Edge Server sees the recipient as internal, and not in the cloud, as the email has been forwarded to the user@tenant.mail.onmicrosoft.com, and Exchange 2010 is authoritative for this namespace. You are missing a configuration that tells the Edge that some emails with certain properties are not internal, but really external and others (those coming back from the cloud) are the only ones to send internal to the on-premises servers.

So what do you do?

Preparation

Before you run the hybrid wizard you need to do the following. If you have already run the wizard that is fine, you will do these steps and run it again.

  1. Install a digital certificate on all your Edge Servers that is issued by a trusted third party (i.e. GoDaddy, Digicert and others). The private key for this certificate needs to be on each server as well, but you do not need to allow the key to be exported again.
  2. Enable the certificate for SMTP, but ensure you do not set it as the default certificate. You do this by using Exchange Management Shell to Get-ExchangeCertificate to key the key’s thumbprint value and then running Enable-ExchangeCertificate –Thumbrint <thumbprintvalue> –Services SMTP. At this point you are prompted if you want to set this certificate as the default certificate. The answer is always No!
  3. If you answer yes, then run the Enable-ExchangeCertificate cmdlet again, but this time for the certificate thumbprint that was the default and set the default back again. If you change the default you will break EdgeSync and internal mail flow for everyone. And you must use the self-signed certificate for EdgeSync and this third party issued certificate for cloud mail flow, as you cannot use the same certificate for both internal and external traffic.
  4. The certificate needs to be the same across all your Edge Servers.
  5. If you are doing multi-forest hybrid, then the certificate is only the same across all the Edge Servers in one Exchange Organization. The next organization in your multi-forest hybrid needs to use a different certificate for all its Edge Servers.
  6. Then take this same certificate and install it on a single Hub Transport server on-premises. The hybrid wizard cannot see what certificates you have on the Edge Servers, so you need to help the wizard along a bit. Again, this certificate needs enabling for SMTP, but not setting as the default certificate.

Running The Hybrid Wizard

Now you can run the hybrid wizard. The important answers you need to include here are that the hub transport server that you pick must be the one that you placed the certificate on, as you cannot pick the Edge Servers that you will use for mail flow in the wizard. But you will need to enter the IP addresses that your Edge Servers are published on the internet as, and you will need to enter the FQDN of the Edge Servers as well.

Complete the wizard and then time for some manual changes.

Manual Changes

The hybrid wizard will have made a send connector on-premises called “Outbound to Office 365”. You need to change this connector to use the Edge Servers as the source servers. Note that if you run the hybrid wizard again, you might need to reset this value back to the Edge Servers. So once all these required changes are made, remember that running the wizard again could constitute an unexpected change and so should be run with care or out of hours.

Use Set-SendConnector “Outbound to Office 365” -SourceTransportServers <EDGE1>,<EDGE2> and this will cause the send connector settings to replicate to the Edge Server.

Next get a copy of the FQDN value from the receive connector that the hybrid wizard created on the hub transport server. This receive connector will be called “Inbound from Office 365” and will be tied to the public IP ranged of Exchange Online Protection. As your Edge Servers receive the inbound emails from EOP, this receive connector will serve no purposes apart from the fact that its settings are the template for your receive connector on the Edge Servers that the wizard cannot modify. The same receive connector will also have a setting called TlsDomainCapabilities and the value of this setting will be mail.protection.outlook.com:AcceptOorgProtocol. AcceptOorgProtocol is the XOORG value that you see referenced on the internet, but it is really called AcceptOorgProtocol and this is the value that allows the Edge Server to distinguish between inbound and outbound mail for your Office 365 tenant.

So on each Edge Server run the following cmdlet in Exchange Management Shell to modify the default receive connector: Set-ReceiveConnector *def* -TlsDomainCapabilities mail.protection.outlook.com:AcceptOorgProtocol -Fqdn <fqdnFromTheInboundReceiveConnectorOnTheHubTransportServer>.

This needs repeating on each Edge Server. The FQDN value ensures that the correct certificate is selected and the TlsDomainCapabilities setting ensures you do not loop email to Office 365 back on-premises again. Other emails using the Default Receive Connector are not affected by this change, apart from now being able to offer the public certificate as well to their inbound partners.

You can now continue with your testing knowing that mail flow is working, so now onto AutoDiscover, clients, free/busy, public folders etc. etc. etc.

OWA and Conditional Access: Inconsistent Error Reports

Posted on 1 CommentPosted in AzureAD, conditional access, EM+S, enterprise mobility + security, exchange, exchange online, Exchange Online Protection, IAmMEC, Outlook

Here is a good error message. Its good, because I could not find any references to it on Google and the fault was nothing to do with the error message:

image

The error says “something went wrong” and “Ref A: a long string of Hex Ref B: AMSEDGE0319 Ref C: Date Time”. The server name in Ref B will change as well. It also says “more details” and if you click that there are no more details, but that text changes to “fewer details”. As far as I have seen, this only appears on Outlook Web Access (OWA).

The error appears under these conditions:

  1. You are enabled for Enterprise Mobility + Security licences in Azure AD
  2. Conditional Access rules are enabled
  3. The device you are on, or the location you are at etc (see the specifics of the conditional access rule) mean that you are outside the conditions allowed to access Outlook Web Access
  4. You browsed directly to https://outlook.office.com or https://outlook.office365.com

What you see in the error message is OWA’s way of telling you that you cannot get to that site from where you are. That you have failed the conditional access tests.

On the other hand, if you visit the Office 365 portal or MyApps (https://portal.office.com or https://myapps.microsoft.com) and click the Mail icon in your Office 365 menu or on the portal homepage then you get a page that says (in the language of your browser):

image or in Welsh, image

This says “you can’t get there from here” and the reasons why you have failed conditional access.

If you were on a device or location that allowed you to connect (such as a device managed by Intune and compliant with Intune rules) then going to OWA directly will work, as will going via the menu.

So how can you avoid this odd error message for your users. For this, you need to replace outlook.office.com with your own custom URL. For OWA you can create a DNS CNAME in your domain for (lets say) webmail that points to outlook.office365.com (for this it will not work if you point the CNAME to outlook.office.com). Your users can now go to webmail.yourdomain.com. This will redirect the user via Azure AD for login and token generation, and as you are redirected via Azure AD you will always see the proper, language relevant, conditional access page.

Administrators, AADConnect and AdminSDHolder Issues (or why are some accounts having permission-issue)

Posted on 1 CommentPosted in AADConnect, AADSync, active directory, AdminSDHolder, dirsync, exchange, exchange online, hybrid, Office 365

AdminSDHolder is something I come across a lot, but find a lot of admins are unaware of it. In brief it is any user that is a member of a protected group (i.e. Domain Admins) will find that their AD permission inheritance and access control lists on their AD object will be reset every hour. Michael B. Smith did a nice write-up on this subject here.

AdminSDHolder is an AD object that determines what the permissions for all protected group members need to be. Why this matters with AADConnect and your sync to Azure Active Directory (i.e. the directory used by Office 365) is that any object that the AADConnect service cannot read cannot be synced, and any object that the AADConnect service cannot write to can be targeted by writeback permissions. This blog post was last updated 18th June 2017 in advance of the release of AADConnect version 1.1.553.0.

For the read permissions this is less of an issue, as the default read permissions by every object is part of a standard Active Directory deployment and so you will find that AdminSDHolder contains this permission and therefore protected objects can be read by AADConnect. This happens in reality becase Authenticated Users have read permissions to lots of attributes on the AdminSDHolder object under the hidden System containing in the domain. Unless your AD permissions are very locked down or AdminSDHolder permissions have been changed to remove Authenticated Users you should have no issue in syncing admin accounts, who of course might have dependencies on mailboxes and SharePoint sites etc. and so need to be synced to the cloud.

Writeback though is a different ball game. Unless you have done AADConnect with Express settings you will find that protected accounts fail during the last stage of AADConnect sync process. You often see errors in the Export profile for your Active Directory that list your admin accounts. Ofter the easiest way to fix this is to enable the Inheritance permission check box on the user account and sync again. The changes are now successfully written but within the hour this inheritance checkbox will be removed and the default permissions as set on AdminSDHolder reapplied to these user accounts. Later changes that need written back from the cloud will result in a failure to writeback again, and again permission issues will be to blame.

To fix this we just need to ensure that the AdminSDHolder object has the correct permissions needed. This is nothing more than doing what the AADConnect Express wizard will do for you anyway, but if you don’t do the Express wizard I don’t think I have seen what you should do documented anywhere – so this is the first (maybe).

Often if you don’t run Express settings you are interested in the principal of least privilege and so the rest of this blog post will outline what you will see in your Active Directory and what to do to ensure protected accounts will always sync and writeback in the Azure Active Directory sync engine. I covered the permissions to enable various types of writeback permissions in a different blog post, but the scripts in this post never added the correct write permissions to AdminSDHolder, so this post will cover what to do for your protected accounts.

First, take a look at any protected account (i.e. one that is a member of Domain Admins):
image

You will see in the Advanced permissions dialog that their is an “Enable Inheritance” button (or a check box is unchecked in older versions of Active Directory. You will also notice that all the permissions under the “Inherited From” column read “None” – that is there are no permissions inherited. You will also see, as shown in the above dialog, that if Express settings have been run for your AADConnect sync service that a access control entry for the AADConnect service account will be listed – here this is MSOL_924f68d9ff1f (yours will be different if it exists) and has read/write for everything. This is not least privilege! If you have run the sync engine previously on different servers and later removed them (as the sync engine can only run on one server to one AAD tenant, excluding staging servers) then you might see more than one MSOL account. The description field of the account will show what server it was created on for your information.

If you compare your above admin account to a non-protected account you will see inheritance can be disabled and that the Inherited From column lists the source of the permission inheritance.

Compare the access control entries (ACE) to the list of ACE’s on the AdminSDHolder object. AdminSDHolder can be found at CN=AdminSDHolder,CN=System,DC=domain,DC=local. You should find that the protected accounts match those of the AdminSDHolder, or at least will within the hour as someone could have just changed something.

Add a permission ACE to AdminSDHolder and it will appear on each protected account within an hour, remove an ACE and it will go within the hour as well. So you could for example remove the MSOL_ account(s) from older ADSync deployments and tidy up your permissions as well.

This is what my Advanced permissions for AdminSDHolder looks like on my domain

image

If I add the relevant ACE’s here for the writeback permissions then within the hour, and then for syncs that happen after that time, the errors for writeback in the sync management console will go away. Note though that AdminSDHolder is per domain, so if you are syncing more than one domain you need to set these permissions on each domain.

To script these permissions, run the following in PowerShell to update AD permissions regarding to the different hybrid writebacks scenarios that you are interested in implementing.

Finding All Your AdminSDHolder Affected Users

The following PowerShell will let you know all the users in your domain who have an AdminCount set to 1 (>0 in reality), which means they are impacted by AdminSDHolder restrictions. The changes below directly on the AdminSDHolder will impact these users as their permissions will get updated to allow writeback from Azure AD.

get-aduser -Filter {admincount -gt 0} -Properties adminCount -ResultSetSize $null | FT DistinguishedName,Enabled,SamAccountName

SourceAnchor Writeback

This setting is needed for all installations since version 1.1.553.0.

$accountName = "domain\aad_account" #[this is the account that will be used by Azure AD Connect Sync to manage objects in the directory, this is an account usually in the form of AAD_number or MSOL_number].
$AdminSDHolder = "CN=AdminSDHolder,CN=System,DC=contoso,DC=com"

$cmd = "dsacls.exe '$AdminSDHolder' /G '`"$accountName`":WP;ms-ds-consistencyGuid'"
Invoke-Expression $cmd | Out-Null

Password Writeback

The following PowerShell will modify the permissions on the AdminSDHolder object so that protected accounts can have Self Service Password Reset (SSPR) function against the accounts. Note you need to change the DC values in the script for it to function against your domain(s).

Note that if you implement this, I recommend that you use version 1.1.553 or later, as that version restricts rogue Azure AD admins from resetting other Active Directory admins passwords and then taking ownership of the Active Directory account. Often Azure AD admins have admin rights in AD, and so this was always possible independent of AADConnect, but versions of AADConnect prior to 1.1.553 would allow an Azure AD admin to reset a restricted AD account that they did not own.

To determine the account name that permissions must be granted to, open the Synchronization Service Manager on the sync server, click Connectors and double click the connector to the domain you are updating. Under the Connect to Active Directory Forest item you will see the Forest Name and User Name. The User Name is the name of the account you need in the script. An example is shown below:

image

$accountName = "domain\aad_account" #[this is the account that will be used by Azure AD Connect Sync to manage objects in the directory, this is an account usually in the form of AAD_number or MSOL_number].
$AdminSDHolder = "CN=AdminSDHolder,CN=System,DC=contoso,DC=com"

$cmd = "dsacls.exe '$AdminSDHolder' /G '`"$accountName`":CA;`"Reset Password`"'"
Invoke-Expression $cmd | Out-Null
$cmd = "dsacls.exe '$AdminSDHolder' /G '`"$accountName`":CA;`"Change Password`"'"
Invoke-Expression $cmd | Out-Null
$cmd = "dsacls.exe '$AdminSDHolder' /G '`"$accountName`":WP;lockoutTime'"
Invoke-Expression $cmd | Out-Null
$cmd = "dsacls.exe '$AdminSDHolder' /G '`"$accountName`":WP;pwdLastSet'"
Invoke-Expression $cmd | Out-Null

Exchange Hybrid Mode Writeback

The below script will set the permissions required for the service account that AADSync uses. Note that if Express mode has been used, then an account called MSOL_AD_Sync_RichCoexistence will exist that has these permissions rather than being assigned directly to the sync account. Therefore you could change the below permissions to utilise MSOL_AD_Sync_RichCoexistence rather than AAD_ or MSOL_ and achieve the same results, but knowing that future changes to the MSOL_ or AAD_ account will be saved as it was done via a group.

The final permission in the set is for msDS-ExternalDirectoryObjectID and this is part of the Exchange Server 2016 (and maybe Exchange Server 2013 later CU’s) schema updates. Newer documentation on AAD Connect synchronized attributes already has this attribute listed, for example in Azure AD Connect sync: Attributes synchronized to Azure Active Directory

$accountName = "domain\aad_account"
$AdminSDHolder = "CN=AdminSDHolder,CN=System,DC=contoso,DC=com"

$cmd = "dsacls '$AdminSDHolder' /G '`"$accountName`":WP;proxyAddresses'"
Invoke-Expression $cmd | Out-Null
$cmd = "dsacls '$AdminSDHolder' /G '`"$accountName`":WP;msExchUCVoiceMailSettings'"
Invoke-Expression $cmd | Out-Null
$cmd = "dsacls '$AdminSDHolder' /G '`"$accountName`":WP;msExchUserHoldPolicies'"
Invoke-Expression $cmd | Out-Null
$cmd = "dsacls '$AdminSDHolder' /G '`"$accountName`":WP;msExchArchiveStatus'"
Invoke-Expression $cmd | Out-Null
$cmd = "dsacls '$AdminSDHolder' /G '`"$accountName`":WP;msExchSafeSendersHash'"
Invoke-Expression $cmd | Out-Null
$cmd = "dsacls '$AdminSDHolder' /G '`"$accountName`":WP;msExchBlockedSendersHash'"
Invoke-Expression $cmd | Out-Null
$cmd = "dsacls '$AdminSDHolder' /G '`"$accountName`":WP;msExchSafeRecipientsHash'"
Invoke-Expression $cmd | Out-Null
$cmd = "dsacls '$AdminSDHolder' /G '`"$accountName`":WP;msDS-ExternalDirectoryObjectID'"
Invoke-Expression $cmd | Out-Null
$cmd = "dsacls '$AdminSDHolder' /G '`"$accountName`":WP;publicDelegates'"
Invoke-Expression $cmd | Out-Null

Once these two scripts are run against AdminSDHolder object and you wait an hour, the permissions will be applied to your protected accounts, then within 30 minutes (based on the default sync time) any admin account that is failing to get cloud settings written back to Active Directory due to permission-issue errors will automatically get resolved.

Exchange Edge Server and Common Attachment Blocking In Exchange Online Protection

Posted on Leave a commentPosted in 2007, 2010, 2013, 2016, Edge, EOP, exchange, exchange online, Exchange Online Protection, FOPE, IAmMEC, Office 365

Both Exchange Server Edge role and Exchange Online Protection have an attachment filtering policy. The default in Edge Server is quite long, and the default in EOP is quite short. There is also a few values that are common to both.

So, how do you merge the lists so that your Edge Server attachment filtering policy is copied to Exchange Online in advance of changing your MX record to EOP?

You run

Set-MalwareFilterPolicy Default -FileTypes ade,adp,cpl,app,bas,asx,bat,chm,cmd,com,crt,csh,exe,fxp,hlp,hta,inf,ins,isp,js,jse,ksh,lnk,mda,mdb,mde,mdt,mdw,mdz,msc,msi,msp,mst,ops,pcd,pif,prf,prg,ps1,ps11,ps11xml,ps1xml,ps2,ps2xml,psc1,psc2,reg,scf,scr,sct,shb,shs,url,vb,vbe,vbs,wsc,wsf,wsh,xnk,ace,ani,docm,jar

This takes both the Edge Server default list and the EOP default list, minus the duplicate values and adds them to EOP. If you have a different custom list then use the following PowerShell to get your two lists and then use the above (with “Default” being the name of the policy) PowerShell to update the list in the cloud

Edge Server: Get-AttachmentFilterEntry

EOP: $variable = Get-MalwareFilterPolicy Default
$variable.FileTypes

Exchange Online Archive–Counting Archives

Posted on Leave a commentPosted in archive, exchange, exchange online, Exchange Server, EXO, IAmMEC, Office 365

If you are using Exchange Online Archive and what to get a count of the number of users with an archive, or a list of the users with an archive, then the following PowerShell scripts will give you this info:

List all users with an Exchange Online Archive:

Get-MailUser -ResultSize Unlimited | where {$_.ArchiveName -ilike “In-Place Archive*”}

Count all users with an Exchange Online Archive:

(Get-MailUser -ResultSize Unlimited | where {$_.ArchiveName -ilike “In-Place Archive*”}).Count

Both of these PowerShell cmdlets need to be run in Exchange Online via Remote PowerShell.

Exchange Server and Missing Root Certificates

Posted on Leave a commentPosted in 2007, 2010, 2013, exchange, exchange online, Exchange Server, federation, Free/Busy

I came across an issue with a clients Exchange Server deployment today that is not well documented – or rather it is, but you need to know where to look. So I thought I would document the troubleshooting steps and the fix here.

We specifically came across this error when testing Free/Busy for an Office 365 migration, though it could happen for a variety of reasons. Free/Busy and other lookups in a cross-forest Exchange Server deployment require a working organization configuration and this was failing. Running Test-FederationTrust (a prerequisite of the organization relationship) in verbose mode (add -Verbose to the end) returned the following:

Unable to retrieve federation metadata from the security token
service. Reason: Microsoft.Exchange.Management.FederationProvisioning.FederationMetadataException: Unable to access the
Federation Metadata document from the federation partner. Detailed information: “The underlying connection was closed:
Could not establish trust relationship for the SSL/TLS secure channel.”.

The final result of the test will also show two errors for “Unable to retrieve federation metadata from the security token service.” and “Failed to request delegation token.”

The last part of the verbose error is the clue here. The server in question is unable to make an SSL/TLS connection to the endpoint that the federation trust needs to reach to get the federation trust metadata. That endpoint is listed right at the start of the Verbose output. It reads:

VERBOSE: [16:53:08.306 GMT] Test-FederationTrust : Requesting Federation Metadata from
https://nexus.microsoftonline-p.com/FederationMetadata/2006-12/FederationMetadata.xml.

Now that we have a URL and an error message, check that the URL is reachable from each of your Exchange Servers. At my client today we found one server could not successfully reach this endpoint without an SSL error turning up in the browser. The problem was that the certificate that the endpoint is secure with is issued by the Baltimore Cybertrust Root Certificate – one that Microsoft uses for lots of services, but the root certificate was not installed on that machine. Lots of root certs where missing from that machine as it had never had a root certificate update applied to it.

We installed the latest Root Certificate Update and then the federation trust worked and free/busy etc. (mail tips, cross-forest message tracking etc.) all worked fine.

Qualifications in Exchange Signatures

Posted on Leave a commentPosted in 2013, active directory, exchange, Exchange Server, Global Catalog, IAmMEC, iQ.Suite

In a recent project I was working with iQ.Suite from GBS and specifically the component of this software that add signatures to emails. The client are an international organization with users in different geographies and we needed to accommodate the users qualifications in their email signature.

The problem with this is that in Germany qualifications are written in front of the name and in the USA at the end and in other countries at the start and the end. We were doing a Notes to Exchange migration and in Notes the iQ.Suite signature software read data from Notes that was originally pulled from Active Directory, and so the client had placed the qualifications in the DisplayName field in the Active Directory.

But when we migrated to Exchange Server the Global Address List listed the users DisplayName an so the German users where all listed together with “Dipl” as the first characters of their name. Also the name the email came from was written like this. The signature worked, but the other changes that became apparent meant we had to work out a different way to look at this problem.

So rather than using DisplayName for the users name and qualifications, we used personalPrefix in Active Directory to store anything needed before their name (Dipl in the above German example, and Prof or Dr being English examples) and the generationQualifier Active Directory attribute to store any string that followed the users DisplayName (such as Jr in the USA or BSc for qualifications etc.)

In iQ.Suite we created a signature that looked like the following. This has a conditional [COND] entry for personalTitle, displayName and generationQualifier. That is if each of these are present, then show the displayName with personalTitle before it and generationQualifier after it. If the user does not have values for these fields, do not show them. The [COND] control is documented in iQ.Suite.

[COND]personalTitle;[VAR]personalTitle[/VAR] [/COND][COND]displayName;[VAR]displayName[/VAR][/COND][COND]generationQualifier; [VAR]generationQualifier[/VAR][/COND]

What was not so well documented, and why I wanted to write this blog entry was that the personalTitle and generationQualifier attributes are not stored in the Global Catalog and so are missing in the users signature. In the multi-domain deployment we had at the client, iQ.Suite read the personalTitle, displayName and generationQualifier Active Directory attributes from the Global Catalog as Exchange was installed in a resource domain and the users in separate domains and so unless the attribute was pushed to the Global Catalog it was not seen by iQ.Suite.

To promote an attribute to be visible in the Global Catalog you need to open the Schema Management MMC snap-in, find the attributes of question and tick the Replicate this attribute to the Global Catalog field. This is outlined in https://technet.microsoft.com/en-us/library/cc737521(v=ws.10).aspx.

Configuring Writeback Permissions in Active Directory for Azure Active Directory Sync

Posted on 40 CommentsPosted in 2008, 2008 R2, 2012, 2012 R2, active directory, ADFS 3.0, Azure, Azure Active Directory, cloud, exchange, exchange online, groups, hybrid, IAmMEC, Office 365, WAP, Web Application Proxy, windows

[Update March 2017 – added another blog post on using the below to fix permission-issue errors on admin and other protected accounts at http://c7solutions.com/2017/03/administrators-aadconnect-and-adminsdholder-issues]

[This blog post was last updated 18th June 2017 in advance of the release of AADConnect version 1.1.553.0. This post contains updates to the below scripts to include the latest attributes synced back to on-premises]

Azure Active Directory has been long the read-only cousin of Active Directory for those Office 365 and Azure users who sync their directory from Active Directory to Azure Active Directory apart from eight attributes for Exchange Server hybrid mode. Not any more. Azure Active Directory writeback is now available and in preview for some of the writeback types at the time of writing. This enabled objects to be mastered or changed in Azure Active Directory and written back to on-premises Active Directory.

This writeback includes:

  • Devices that can be enrolled with Office 365 MDM or Intune, which will allow login to AD FS controlled resources based on user and the device they are on
  • “Modern Groups” in Office 365 can be written back to on-premises Exchange Server 2013 CU8 or later hybrid mode and appear as mail enabled distribution lists on premises. Does not require AAD Premium licences
  • Users can change their passwords via the login page or user settings in Office 365 and have that password written back online.
  • Exchange Server hybrid writeback is the classic writeback from Azure AD and is the apart from Group Writeback is the only one of these writebacks that does not require Azure AD Premium licences.
  • User writeback from Azure AD (i.e. users made in Office 365 in the cloud for example) to on-premises Active Directory
  • Windows 10 devices for “Azure AD Domain Join” functionality

All of these features (apart from Exchange Hybrid writeback) require AADConnect and not and of the earlier verions (which will be actively blocked by the end of 2017 anyway). Install and run the AADConnect program to migrate from DirSync to AADSync and then in the Synchronization Options on rerunning the AADConnect wizard you can add all these writeback functions.

In all the below sections you need to grant permission to the connector account. You can find the connector account for your Active Directory forest from the Synchronization Service program > Connectors > double-click your domain > select Connect to Active Directory Forest. The account listed here is the connector account you need to grant permissions to.

SourceAnchor Writeback

For users with (typically) multi-forest deployments or plans or a forest migration, the objectGuid value in Active Directory, which is used as the source for the attribute that keys your on-premises object to your synced cloud object – in AAD sync parlance, this is known as the SourceAnchor. If you set up AADConnect version 1.1.553.0 or later you can opt to change from objectGuid to a new source anchor attribute known as ms-ds-consistencyGuid. To be able to use this new feature you need the ability for AADConnect connector account to be able to read ObjectGUID and then write it back to ms-ds-consistencyGuid. The read permissions are typically available to the connector account without doing anything special, and if AADConnect is installed in Express Mode it will get the write permissions it needs, but as with the rest of this blog, if you are not using Express Mode you need to grant the permissions manually and so write permissions are needed to the ms-ds-consistencyGuid attribute. This can be done with this script.


$accountName = "domain\aad_account" #[this is the account that will be used by Azure AD Connect Sync to manage objects in the directory, this is often an account in the form of MSOL_number or AAD_number].
$ForestDN = "DC=contoso,DC=com"

$cmd = "dsacls '$ForestDN' /I:S /G '`"$accountName`":WP;ms-ds-consistencyGuid;user'"
Invoke-Expression $cmd | Out-Null

Note that if you use ms-ds-consistencyGuid then there are changes required on your ADFS deployment as well. The Issuance Transform Rules for the Office 365 Relying Party Trust contains a rule that specifies the ImmutableID (aka AADConnect SourceAnchor) that the user will be identified as for login. By default this is set to ObjectGUID, and if you use AADConnect to set up ADFS for you then the application will update the rule. But if you set up ADFS yourself then you need to update the rule.

Issuance Transform Rules

When Office 365 is configured to federate a domain (use ADFS for authentication of that domain and not Azure AD) then the following are the claims rules that exist out of the box need to be adjusted. This is to support the use of ms-ds-consistencyguid as the immutable ID.

ADFS Management UI > Trust Relationships > Relying Party Trusts

Select Microsoft Office 365 Identity Platform > click Edit Claim Rules

You get two or three rules listed here. You get three rules if you use -SupportMultipleDomain switch in Convert-MSOLDomainToFederated.
Rule 1:
Change objectGUID to ms-DS-ConsistencyGUID
Rule Was:
c:[Type == “http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname”]
=> issue(store = “Active Directory”, types = (“http://schemas.xmlsoap.org/claims/UPN”, “http://schemas.microsoft.com/LiveID/Federation/2008/05/ImmutableID”), query = “samAccountName={0};userPrincipalName,objectGUID;{1}”, param = regexreplace(c.Value, “(?<domain>[^\\]+)\\(?<user>.+)”, “${user}”), param = c.Value);
New Value:
c:[Type == “http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname”]
=> issue(store = “Active Directory”, types = (“http://schemas.xmlsoap.org/claims/UPN”, “http://schemas.microsoft.com/LiveID/Federation/2008/05/ImmutableID”), query = “samAccountName={0};userPrincipalName,ms-DS-ConsistencyGUID;{1}”, param = regexreplace(c.Value, “(?<domain>[^\\]+)\\(?<user>.+)”, “${user}”), param = c.Value);

Preparing for Device Writeback

If you do not have a 2012 R2 or later domain controller then you need to update the schema of your forest. Do this by getting a Windows Server 2012 R2 ISO image and mounting it as a drive. Copy the support/adprep folder from this image or DVD to a 64 bit domain member in the same site as the Schema Master. Then run adprep /forestprep from an admin cmd prompt when logged in as a Schema Admin. The domain member needs to be a 64 bit domain joined machine for adprep.exe to run.

Wait for the schema changes to replicate around the network.

Import the cmdlets needed to configure your Active Directory for writeback by running Import-Module ‘C:\Program Files\Microsoft Azure Active Directory Connect\AdPrep\AdSyncPrep.psm1’ from an administrative PowerShell session. You need Azure AD Global Admin and Enterprise Admin permissions for Azure and local AD forest respectively. The cmdlets for this are obtained by running the Azure AD Connect tool.


$accountName = "domain\aad_account" #[this is the account that will be used by Azure AD Connect Sync to manage objects in the directory, this is often an account in the form of MSOL_number or AAD_number].
Initialize-ADSyncDeviceWriteBack -AdConnectorAccount $accountName -DomainName contoso.com #[domain where devices will be created].

This will create the “Device Registration Services” node in the Configuration partition of your forest as shown:

image

To see this, open Active Directory Sites and Services and from the View menu select Show Services Node. Also in the domain partition you should now see an OU called RegisteredDevices. The AADSync account now has permissions to write objects to this container as well.

In Azure AD Connect, if you get the error “This feature is disabled because there is no eligible forest with appropriate permissions for device writeback” then you need to complete the steps in this section and click Previous in the AADConnect wizard to go back to the “Connect your directories” page and then you can click Next to return to the “Optional features” page. This time the Device Writeback option will not be greyed out.

Device Writeback needs a 2012 R2 or later AD FS server and WAP to make use of the device info in the Active Directory (for example, conditional access to resources based on the user and the device they are using). Once Device Writeback is prepared for with these cmdlets and the AADConnect Synchronization Options page is enabled for Device Writeback then the following will appear in Active Directory:

image

Not shown in the above, but adding the Display Name column in Active Directory Users and Computers tells you the device name. The registered owner and registered users of the device are available to view, but as they are SID values, they are not really readable.

If you have multiple forests, then you need add the SCP record for the tenant name in each separate forest. The above will do it for the forest AADConnect is installed in and the below script can be used to add the SCP to other forests:

$verifiedDomain = "contoso.com"  # Replace this with any of your verified domain names in Azure AD
$tenantID = "27f998bf-86f2-41bf-91ab-2d7ab011df35"  # Replace this with you tenant ID
$configNC = "CN=Configuration,DC=corp,DC=contoso,DC=com"  # Replace this with your AD configuration naming context
$de = New-Object System.DirectoryServices.DirectoryEntry
$de.Path = "LDAP://CN=Services," + $configNC
$deDRC = $de.Children.Add("CN=Device Registration Configuration", "container")
$deDRC.CommitChanges()
$deSCP = $deDRC.Children.Add("CN=62a0ff2e-97b9-4513-943f-0d221bd30080", "serviceConnectionPoint")
$deSCP.Properties["keywords"].Add("azureADName:" + $verifiedDomain)
$deSCP.Properties["keywords"].Add("azureADId:" + $tenantID)
$deSCP.CommitChanges()

Preparing for Group Writeback

Writing Office 365 “Modern Groups” back to Active Directory on-premises requires Exchange Server 2013 CU8 or later schema updates and servers installed. To create the OU and permissions required for Group Writeback you need to do the following.

Import the cmdlets needed to configure your Active Directory for writeback by running Import-Module ‘C:\Program Files\Microsoft Azure Active Directory Connect\AdPrep\AdSyncPrep.psm1’ from an administrative PowerShell session. You need Domain Admin permissions for the domain in the local AD forest that you will write back groups to. The cmdlets for this are obtained by running the Azure AD Connect tool.

$accountName = "domain\aad_account" #[this is the account that will be used by Azure AD Connect Sync to manage objects in the directory, this is often an account in the form of MSOL_number or AAD_number].
$cloudGroupOU = "OU=CloudGroups,DC=contoso,DC=com"
Initialize-ADSyncGroupWriteBack -AdConnectorAccount $accountName -GroupWriteBackContainerDN $cloudGroupOU

Once these cmdlets are run the AADSync account will have permissions to write objects to this OU. You can view the permissions in Active Directory Users and Computers for this OU if you enable Advanced mode in that program. There should be a permission entry for this account that is not inherited from the parent OU’s.

At the time of writing, the distribution list that is created on writeback from Azure AD will not appear in the Global Address List in Outlook etc. or allow on-premises mailboxes to send to these internal only cloud based groups. To add it to the address book you need to create a new subdomain, update public DNS and add send connectors to hybrid Exchange Server. This is all outlined in https://technet.microsoft.com/en-us/library/mt668829(v=exchg.150).aspx. This ensure’s that on-premises mailboxes can deliver to groups as internal senders and not require external senders enabled on the group. To add the group to the Global Address List you need to run Update-AddressList in Exchange Server. Once group writeback is prepared for using these cmdlets here and AADConnect has had it enabled during the Synchronization Options page, you should see the groups appearing in the selected OU as shown:

image

And you should find that on-premises users can send email to these groups as well.

Preparing for Password Writeback

The option for users to change their passwords in the cloud and have then written back to on-premises (with multifactor authentication and proof of right to change the password) is also available in Office 365 / Azure AD with the Premium Azure Active Directory or Enterprise Mobility Pack licence.

To enable password writeback for AADConnect you need to enable the Password Writeback option in AADConnect synchronization settings and then run the following three PowerShell cmdlets on the AADSync server:


Get-ADSyncConnector | fl name,AADPasswordResetConfiguration
Get-ADSyncAADPasswordResetConfiguration -Connector "contoso.onmicrosoft.com - AAD"
Set-ADSyncAADPasswordResetConfiguration -Connector "contoso.onmicrosoft.com - AAD" -Enable $true

The first of these cmdlets lists the ADSync connectors and the name and password reset state of the connector. You need the name of the AAD connector. The middle cmdlet tells you the state of password writeback on that connector and the last cmdlet enables it if needed. The name of the connector is required in these last two cmdlets.

To set the permissions on-premises for the passwords to be written back the following script is needed:

$passwordOU = "DC=contoso,DC=com" #[you can scope this down to a specific OU]
$accountName = "domain\aad_account" #[this is the account that will be used by Azure AD Connect Sync to manage objects in the directory, this is often an account in the form of MSOL_number or AAD_number].

$cmd = "dsacls.exe '$passwordOU' /I:S /G '`"$accountName`":CA;`"Reset Password`";user'"
Invoke-Expression $cmd | Out-Null

$cmd = "dsacls.exe '$passwordOU' /I:S /G '`"$accountName`":CA;`"Change Password`";user'"
Invoke-Expression $cmd | Out-Null

$cmd = "dsacls.exe '$passwordOU' /I:S /G '`"$accountName`":WP;lockoutTime;user'"
Invoke-Expression $cmd | Out-Null

$cmd = "dsacls.exe '$passwordOU' /I:S /G '`"$accountName`":WP;pwdLastSet;user'"
Invoke-Expression $cmd | Out-Null

Finally you need to run the above once per domain.

Preparing for Exchange Server Hybrid Writeback

Hybrid mode in Exchange Server requires the writing back on eight attributes from Azure AD to Active Directory. The list of attributes written back is found here. The following script will set these permissions for you in the OU you select (or as shown at the root of the domain). The DirSync tool used to do all this permissioning for you, but the AADSync tool does not. Therefore scripts such as this are required. This script sets lots of permissions on these eight attributes, but for clarify on running the script the output of the script is sent to Null. Remove the “| Out-Null” from the script to see the changes as they occur (the script also takes a lot longer to run).

$accountName = "domain\aad_account" #[this is the account that will be used by Azure AD Connect Sync to manage objects in the directory, this is often an account in the form of MSOL_number or AAD_number].
$HybridOU = "DC=contoso,DC=com"

#Object type: user
$cmd = "dsacls '$HybridOU' /I:S /G '`"$accountName`":WP;proxyAddresses;user'"
Invoke-Expression $cmd | Out-Null
$cmd = "dsacls '$HybridOU' /I:S /G '`"$accountName`":WP;msExchUCVoiceMailSettings;user'"
Invoke-Expression $cmd | Out-Null
$cmd = "dsacls '$HybridOU' /I:S /G '`"$accountName`":WP;msExchUserHoldPolicies;user'"
Invoke-Expression $cmd | Out-Null
$cmd = "dsacls '$HybridOU' /I:S /G '`"$accountName`":WP;msExchArchiveStatus;user'"
Invoke-Expression $cmd | Out-Null
$cmd = "dsacls '$HybridOU' /I:S /G '`"$accountName`":WP;msExchSafeSendersHash;user'"
Invoke-Expression $cmd | Out-Null
$cmd = "dsacls '$HybridOU' /I:S /G '`"$accountName`":WP;msExchBlockedSendersHash;user'"
Invoke-Expression $cmd | Out-Null
$cmd = "dsacls '$HybridOU' /I:S /G '`"$accountName`":WP;msExchSafeRecipientsHash;user'"
Invoke-Expression $cmd | Out-Null
$cmd = "dsacls '$HybridOU' /I:S /G '`"$accountName`":WP;msDS-ExternalDirectoryObjectID;user'"
Invoke-Expression $cmd | Out-Null
$cmd = "dsacls '$HybridOU' /I:S /G '`"$accountName`":WP;publicDelegates;user'"
Invoke-Expression $cmd | Out-Null

#Object type: iNetOrgPerson
$cmd = "dsacls '$HybridOU' /I:S /G '`"$accountName`":WP;proxyAddresses;iNetOrgPerson'"
Invoke-Expression $cmd | Out-Null
$cmd = "dsacls '$HybridOU' /I:S /G '`"$accountName`":WP;msExchUCVoiceMailSettings;iNetOrgPerson'"
Invoke-Expression $cmd | Out-Null
$cmd = "dsacls '$HybridOU' /I:S /G '`"$accountName`":WP;msExchUserHoldPolicies;iNetOrgPerson'"
Invoke-Expression $cmd | Out-Null
$cmd = "dsacls '$HybridOU' /I:S /G '`"$accountName`":WP;msExchArchiveStatus;iNetOrgPerson'"
Invoke-Expression $cmd | Out-Null
$cmd = "dsacls '$HybridOU' /I:S /G '`"$accountName`":WP;msExchSafeSendersHash;iNetOrgPerson'"
Invoke-Expression $cmd | Out-Null
$cmd = "dsacls '$HybridOU' /I:S /G '`"$accountName`":WP;msExchBlockedSendersHash;iNetOrgPerson'"
Invoke-Expression $cmd | Out-Null
$cmd = "dsacls '$HybridOU' /I:S /G '`"$accountName`":WP;msExchSafeRecipientsHash;iNetOrgPerson'"
Invoke-Expression $cmd | Out-Null
$cmd = "dsacls '$HybridOU' /I:S /G '`"$accountName`":WP;msDS-ExternalDirectoryObjectID;iNetOrgPerson'"
Invoke-Expression $cmd | Out-Null
$cmd = "dsacls '$HybridOU' /I:S /G '`"$accountName`":WP;publicDelegates;iNetOrgPerson'"
Invoke-Expression $cmd | Out-Null

#Object type: group
$cmd = "dsacls '$HybridOU' /I:S /G '`"$accountName`":WP;proxyAddresses;group'"
Invoke-Expression $cmd | Out-Null

#Object type: contact
$cmd = "dsacls '$HybridOU' /I:S /G '`"$accountName`":WP;proxyAddresses;contact'"
Invoke-Expression $cmd | Out-Null

Finally you need to run the above once per domain.

Preparing for User Writeback

[This functionality is not in the current builds of AADConnect]

Currently in preview at the time of writing, you are able to make users in Azure Active Directory (cloud users as Office 365 would call them) and write them back to on-premises Active Directory. The users password is not written back and so needs changing before the user can login on-premises.

To prepare the on-premises Active Directory to writeback user objects you need to run this script. This is contained in AdSyncPrep.psm1 and that is installed as part of Azure AD Connect. Azure AD Connect will install Azure AD Sync, which is needed to do the writeback. To load the AdSyncPrep.psm1 module into PowerShell run Import-Module ‘C:\Program Files\Microsoft Azure Active Directory Connect\AdPrep\AdSyncPrep.psm1’ from an administrative PowerShell session.

$accountName = "domain\aad_account" #[this is the account that will be used by Azure AD Connect Sync to manage objects in the directory, this is an account usually in the form of AAD_number].
$cloudUserOU = "OU=CloudUsers,DC=contoso,DC=com"
Initialize-ADSyncUserWriteBack -AdConnectorAccount $accountName -UserWriteBackContainerDN $cloudUserOU

Once the next AADSync occurs you should see users in the OU used above that match the cloud users in Office 365 as shown:

image

Prepare for Windows 10 Registered Device Writeback Sync

Windows 10 devices that are joined to your domain can be written to Azure Active Directory as a registered device, and so conditional access rules on device ownership can be enforced. To do this you need to import the AdSyncPrep.psm1 module. This module supports the following two additional cmdlets to prepare your Active Directory for Windows 10 device sync:

CD "C:\Program Files\Microsoft Azure Active Directory Connect\AdPrep"
Import-Module .\AdSyncPrep.psm1
Initialize-ADSyncDomainJoinedComputerSync
Initialize-ADSyncNGCKeysWriteBack

These cmdlets are run as follows:

$accountName = "domain\aad_account" #[this is the account that will be used by Azure AD Connect Sync to manage objects in the directory, this is often an account in the form of MSOL_number or AAD_number].
$azureAdCreds = Get-Credential #[Azure Active Directory administrator account]

CD "C:\Program Files\Microsoft Azure Active Directory Connect\AdPrep"
Import-Module .\AdSyncPrep.psm1
Initialize-ADSyncDomainJoinedComputerSync -AdConnectorAccount $accountName -AzureADCredentials $azureAdCreds 
Initialize-ADSyncNGCKeysWriteBack -AdConnectorAccount $accountName 

Once complete, open Active Directory Sites and Services and from the View menu Show Services Node. Then you should see the GUID of your domain under the Device Registration Configuration container.

image