Windows 10 Enterprise domain join options

When running Windows 10 setup from enterprise media, one of the options presented is to choose how you’ll connect Windows to your organisation.

  • Join Azure AD
  • Join a domain

You might ask, “where’s the option to just continue as normal and stay in a workgroup?” (as a non-domain-joined PC) but the explanatory text helps:

  • Join Azure AD if your organisation uses Office 365 or other business services from Microsoft.
  • If you plan to join the PC to a domain, a local account is created and then you can join a domain as in previous Windows OSes once setup is complete.

The “join a domain” option doesn’t actually join a domain at all – indeed, once you’ve elected to join a domain you can switch to signing in with a Microsoft account (and gain the benefits of settings being synchronised between PCs) as well as adding a workplace or school account (signing in to Office 365, for example), changing sign-in options, joining/leaving a domain and/or joining/leaving Azure AD (for administrators to manage the PC in line with policy).

Windows 10 - Accounts - Your Accounts

Windows 10 - Accounts - Signin Options

Windows 10 - Accounts - Work Access

Overview of Azure AD synchronisation

Over the last few months, I’ve had the opportunity to work with a number of directories that are synchronised from on-premises Active Directory (AD) to Azure AD (AAD) – the directory service behind Office 365, Azure, Dynamics, Intune and other business-focused Microsoft online services.

I’ve learned a few things along the way (like that AAD synchronisation servers are disposable and shouldn’t be re-configured to sync with a different directory, as well as some steps for troubleshooting missing objects) but I thought I’d group a few more points together in this post.

DirSync -> AAD Sync -> AAD Connect

There have been various versions of what’s essentially the same tool (a customised implementation of Microsoft Identity Manager, previously known as Forefront Identity Manager and Microsoft Identity Integration Server – indeed the Synchronisation Manager is still named miisclient.exe) and Paul Wooldridge does a great job of summarising the current situation in his blog post for risual.

These days, there are very few reasons not to be using the latest version – Azure AD Connect – which massively simplifies the process of configuring the underlying Azure AD Synchronisation Services as well as including a number of optional preview features for new functionality. The one caveat is that it needs Windows Server 2012 or later.

Hardware, software and service accounts

Whilst there’s no reason a physical machine couldn’t be used, all of the Azure AD synchronisation servers I’ve worked on have been virtual.  The machine will require the following specification:

  • Windows Server 2008 or later (standalone or domain joined).
  • Microsoft .Net framework version 4.5.1.
  • PowerShell (v3 or later).
  • Local administrator privileges to install the software.
  • Unauthenticated Internet access (over port 443) to the Office 365 servers.
  • A regular user account to connect to AD and read the attributes for objects to be synchronised. This must be able to log on as a service and it will also need to be granted the following permissions in order to write back password hashes (for same sign on):
    • Replicating Directory Changes.
    • Replicating Directory Changes All.

Older versions of the tool allowed the administrator to define an account in the cloud whereas AAD Connect asks for credentials and creates its own service account (with a display name of On-Premises Directory Synchronization Service Account and an user name of Also, unlike previous versions the account is set with a password that will not expire (the PasswordNeverExpires and PasswordResetNotRequiredDuringActivate attributes are both set to $true).

Tools and commands

Azure AD Connect is based on the Azure AD Synchronization Services framework which itself is evolved from Microsoft Identity Manager (formerly Forefront Identity Manager, Microsoft Identity Lifecycle Manager, Microsoft Identity Integration Server, Microsoft Metadirectory Server and Zoomit Via before that!). Not surprisingly, the underlying tools are the same ones used for these products!

  • The main tool is the Synchronization Service Manager (miisclient.exe), which is used to monitor synchronisation as well as to adjust the scope of synchronisation (more on that in a moment)
  • There’s also a Rules Editor (which I leave alone – indeed, directly editing the rules is not supported for AAD Connect)
  • A scheduled task is also created that runs the synchronisation process every 3 hours by default (you may want to reduce the timeout on this to avoid issues with long-running syncs too).
  • It’s possible to force a synchronisation from the command line. This can also be done from the Synchronization Service Manager or from Task Scheduler but the command line is easy! Simply run directorysyncclientcmd.exe delta (from an PowerShell session running as Administrator) or directorysyncclientcmd.exe initial to force a full synchronisation.

As for Powershell cmdlets, the documentation on the ADSync PowerShell module is pretty poor. I managed to extract a list of commands and their syntax but there’s no meaningful help text (at least not that I’ve found). I’ve also seen that the DirSync information on the synced attributes is better than the AAD Sync information (which warns it will be archived soon) and I haven’t found the equivalent AAD Connect information!

What gets synchronised?

For many organisations, not all of the directory needs to be synchronised. It’s possible to filter synchronisation by domain, organizational unit (OU), group membership, or directory attribute. Of these, group membership is generally only used in test (it quickly becomes tiresome to add users to a group to ensure that they are synced to the cloud) and OU filtering is the most common form I’ve seen. It’s also worth noting that the group membership option is new with Azure AD Connect and previous versions of the tool didn’t allow this.

Also note that, if the scope of synchronisation is changed, a full synchronisation is required as a delta will not pick up the new filtering arrangements.

Further reading

PowerShell cmdlets in the Azure ADSync module

MVP, Mike Crowley wrote a blog post last year that details the cmdlets for managing Azure AD Directory Synchronisation (DirSync). Unfortunately, the latest incarnation of DirSync (Azure AD Connect) uses a totally different set of commands (and they seem to me to be more complex to use – thank goodness the GUI is so good now).

I used Mike’s method to extract the details of the PowerShell cmdlets in the Azure ADSync module:

Import-Module ADSync
Get-Command -Module ADSync | Get-Help | Select name, synopsis | Export-Csv $env:userprofile\Desktop\DirSyncCmdlets.csv -NoTypeInformation

Unfortunately the help information is very sparse so the synopsis is missing.  Aaron Peterson has some extra information on the ADSync cmdlets but it seems we’ve gone backwards in terms of help…

My final attempt was Get-Command -Module ADSync | Select definition | Export-Csv $env:userprofile\Desktop\DirSyncCmdlets.csv -NoTypeInformation which allowed me to at least pull out the syntax for each cmdlet:

Add-ADSyncAADServiceAccount [-AADCredential]  [[-Name] ] []
Add-ADSyncAttributeFlowMapping [-SynchronizationRule]  [-AttributeFlowMappings] <List[AttributeFlowMapping]> [-Direction ] [-WhatIf] [-Confirm] []
Add-ADSyncAttributeFlowMapping [[-Source] <List[string]>] [-Destination]  [-FlowType]  [[-ValueMergeType] ] [-SynchronizationRule ] [-Expression ] [-ExecuteOnce] [-Direction ] [-WhatIf] [-Confirm] []
Add-ADSyncConnector [[-Connector] ] []
Add-ADSyncConnector [-Name]  [-Type]  [-Description ] [-ConnectivityParameterSettings ] [-GlobalParameterSettings ] [-HierarchyProvisioningMappings <Dictionary[string,string]>] [-Partitions <List[ConnectorPartition]>] [-PasswordManagementSettings ] []
Add-ADSyncConnectorAnchorConstructionSettings [-Connector]  [-ObjectClass]  [-Locked]  [-Attributes] <List[string]> []
Add-ADSyncConnectorAttributeInclusion [-Connector]  [-AttributeTypes] <List[string]> []
Add-ADSyncConnectorHierarchyProvisioningMapping [-Connector ] [-Mappings <Dictionary[string,string]>] []
Add-ADSyncConnectorHierarchyProvisioningMapping [-Connector]  [[-DNComponent] ] [[-ObjectClass] ] []
Add-ADSyncConnectorObjectInclusion [-Connector]  [-ObjectTypes] <List[string]> []
Add-ADSyncGlobalSettingsParameter [-GlobalSettings]  [-ParameterValuesTable]  []
Add-ADSyncGlobalSettingsParameter [-GlobalSettings]  [-Parameters] <List[ConfigurationParameter]> []
Add-ADSyncJoinConditionGroup [-SynchronizationRule]  [-JoinConditions] <List[JoinCondition]> [-WhatIf] [-Confirm] []
Add-ADSyncRule [-SynchronizationRule]  [-WhatIf] [-Confirm] []
Add-ADSyncRule -Name  -Connector  -Direction  -SourceObjectType  -TargetObjectType  [-Precedence ] [-PrecedenceAfter ] [-PrecedenceBefore ] [-Description ] [-Identifier ] [-ImmutableTag ] [-ScopeFilter <List[ScopeConditionGroup]>] [-JoinFilter <List[JoinConditionGroup]>] [-LinkType ] [-EnablePasswordSync] [-AttributeFlowMappings <List[AttributeFlowMapping]>] [-SoftDeleteExpiryInterval ] [-WhatIf] [-Confirm] []
Add-ADSyncRunProfile [-RunProfile]  []
Add-ADSyncRunProfile [-Name]  [-ConnectorIdentifier]  [-RunSteps <List[RunStep]>] []
Add-ADSyncRunProfile [-Name ] [-ConnectorIdentifier ] [-RunStepPartitionIdentifier ] [-RunStepTask ] [-RunStepObjectProcessLimit ] [-RunStepObjectDeleteLimit ] [-RunStepBatchSize ] [-RunStepLogType ] [-RunStepLogFile ] []
Add-ADSyncRunStep [-RunProfile]  [-PartitionIdentifier]  [-StepTask]  [-BatchSize ] [-ConnectorType ] [-Index ] [-LogType ] [-LogFile ] [-ObjectProcessLimit ] [-ObjectDeleteLimit ] [-PageSize ] [-Timeout ] []
Add-ADSyncScopeConditionGroup [-SynchronizationRule]  [-ScopeConditions] <List[ScopeCondition]> [-WhatIf] [-Confirm] []
Disable-ADSyncConnectorPartition [-Partitions] <List[ConnectorPartition]> [-Connector ] []
Disable-ADSyncConnectorPartition [-Connector]  [-Partition]  []
Disable-ADSyncConnectorPartitionHierarchy [-Connector]  [-Partition]  [-PartitionHierarchyNode]  []
Disable-ADSyncExportDeletionThreshold [-AADCredential]  [-WhatIf] [-Confirm] []
Enable-ADSyncConnectorPartition [-Partitions] <List[ConnectorPartition]> [-Connector ] []
Enable-ADSyncConnectorPartition [-Connector]  [-Partition]  []
Enable-ADSyncConnectorPartitionHierarchy [-Connector]  [-Partition]  [-PartitionHierarchyNode]  []
Enable-ADSyncExportDeletionThreshold [-AADCredential]  [-DeletionThreshold]  [-WhatIf] [-Confirm] []
Get-ADSyncAADPasswordResetConfiguration [-Connector]  []
Get-ADSyncAADPasswordSyncConfiguration [-SourceConnector]  []
Get-ADSyncConnector [-Identifier ] [-Name ] []
Get-ADSyncConnectorHierarchyProvisioningDNComponent [-Connector]  [[-ObjectType] ] [-ShowHidden] []
Get-ADSyncConnectorHierarchyProvisioningMapping [-Connector]  []
Get-ADSyncConnectorHierarchyProvisioningObjectClass [-DNComponent]  []
Get-ADSyncConnectorParameter -Type  [-Identifier ] [-Connector ] [-ScopeIdentifier ] []
Get-ADSyncConnectorPartition [-Connector]  [-Identifier ] [-Name ] []
Get-ADSyncConnectorPartitionHierarchy [-Connector]  [-Partition]  [-ParentPartitionHierarchyNode ] []
Get-ADSyncConnectorTypes []
Get-ADSyncGlobalSettings [-WhatIf] [-Confirm] []
Get-ADSyncGlobalSettingsParameter []
Get-ADSyncRule [[-Identifier] ] [-WhatIf] [-Confirm] []
Get-ADSyncRunProfile [-Connector]  []
Get-ADSyncRunProfile [-Identifier]  []
Get-ADSyncSchema [-Connector ] [-Identifier ] []
Get-ADSyncServerConfiguration [-Path]  []
New-ADSyncConnector [-Name]  [-Type]  [-Description ] [-ExtensionFileName ] []
New-ADSyncJoinCondition [-CSAttribute]  [-MVAttribute]  [[-CaseSensitive] ] [-WhatIf] [-Confirm] []
New-ADSyncRule [-Name]  [-Direction]  [-Connector]  [-SourceObjectType]  [-TargetObjectType]  [-LinkType]  [-Precedence ] [-EnablePasswordSync] [-PrecedenceAfter ] [-PrecedenceBefore ] [-Description ] [-ImmutableTag ] [-Identifier ] [-SoftDeleteExpiryInterval ] [-WhatIf] [-Confirm] []
New-ADSyncRunProfile [-Connector]  [-Name]  []
New-ADSyncScopeCondition [-Attribute]  [-ComparisonValue]  [-ComparisonOperator]  [-WhatIf] [-Confirm] []
Remove-ADSyncAADPasswordResetConfiguration [-Connector]  [[-AADCredential] ] []
Remove-ADSyncAADPasswordSyncConfiguration [-SourceConnector]  []
Remove-ADSyncAADServiceAccount [-AADCredential]  [-Name]  [-WhatIf] [-Confirm] []
Remove-ADSyncAttributeFlowMapping [-SynchronizationRule]  [-AttributeFlowMappings] <List[AttributeFlowMapping]> [-WhatIf] [-Confirm] []
Remove-ADSyncConnector [[-Connector] ] [-WhatIf] [-Confirm] []
Remove-ADSyncConnector [[-Identifier] ] [-WhatIf] [-Confirm] []
Remove-ADSyncConnector [[-Name] ] [-WhatIf] [-Confirm] []
Remove-ADSyncConnectorAnchorConstructionSettings [-Connector]  [-ObjectClass]  []
Remove-ADSyncConnectorAttributeInclusion [-Connector]  [-AttributeTypes] <List[string]> []
Remove-ADSyncConnectorHierarchyProvisioningMapping [-Connector]  [-DNComponent ] [-WhatIf] [-Confirm] []
Remove-ADSyncConnectorHierarchyProvisioningMapping [-DNComponent]  [-Connector ] [-DNComponents <List[string]>] [-WhatIf] [-Confirm] [
Remove-ADSyncConnectorObjectInclusion [-Connector]  [-ObjectTypes] <List[string]> []
Remove-ADSyncGlobalSettingsParameter [-GlobalSettings]  [-ParameterNames] <List[string]> []
Remove-ADSyncJoinConditionGroup [-SynchronizationRule]  [-Index]  [-WhatIf] [-Confirm] []
Remove-ADSyncRule [-SynchronizationRule]  [-WhatIf] [-Confirm] []
Remove-ADSyncRule [-Identifier]  [-WhatIf] [-Confirm] []
Remove-ADSyncRunProfile [-RunProfile]  [-WhatIf] [-Confirm] []
Remove-ADSyncRunStep [-RunProfile]  [-RunStep]  [-WhatIf] [-Confirm] [
Remove-ADSyncScopeConditionGroup [-SynchronizationRule]  [-Index]  [-WhatIf] [-Confirm] []
Search-ADSyncDirectoryObjects [[-ForestFqdn] ] [-AdConnectorId]  [[-PropertiesToRetrieve] <string[]>] [[-NamingContextType] ] [[-BaseDnType] ] [[-AdConnectorCredential] ] [[-BaseDn] ] [[-LdapFilter] ] [[-SearchScope] ] [-WhatIf] [-Confirm] []
Set-ADSyncAADCompanyFeature [-ConnectorName]  [-ForcePasswordResetOnLogonFeature ] [-PasswordHashSyncFeature ] []
Set-ADSyncAADPasswordResetConfiguration [-Connector]  [-Enable]  [[-AADCredential] ] []
Set-ADSyncAADPasswordSyncConfiguration [-SourceConnector]  [-TargetConnector]  [-Enable]  [[-PasswordAgentCredentials] ] []
Set-ADSyncAADPasswordSyncState [-ConnectorName]  [-Enable]  []
Set-ADSyncConnectorParameter -Type  [-Connector ] [-PartitionIdentifier ] [-RunProfileIdentifier ] [-RunStepIdentifier ] [-ParameterValues ] []
Set-ADSyncGlobalSettings [-GlobalSettings]  [-WhatIf] [-Confirm] []
Set-ADSyncSchema [-Schema]  []
Set-ADSyncSchema [-SchemaFile]  []
Set-ADSyncServerConfiguration [-Path]  []
Set-MIISADMAConfiguration [-Id]  -Credentials  -Forest  [-Container ] [-AllowUnreachableDomains] [-WhatIf] [-Confirm] []
Test-AdSyncUserHasPermissions [-ForestFqdn]  [-AdConnectorId]  [-AdConnectorCredential]  [-BaseDn]  [-PropertyType]  [-PropertyValue]  [-WhatIf] [-Confirm] []
Update-ADSyncConnectorPartition [-Connector]  []
Update-ADSyncConnectorSchema [-Connector]  [-WhatIf] [-Confirm] []
Update-ADSyncDRSCertificates [-DeviceWriteBackConnectorName]  [-AadConnectorName]  [-WhatIf] [-Confirm] []

Troubleshooting missing objects in Azure AD sync

I have a half-written blog post about Microsoft Azure Active Directory (AAD) Connect – the latest incarnation of the directory synchronisation engine used to populate a cloud directory for Office 365 and other online services. That post will stay half-written for a while longer as it needs a bit more work but, yesterday, I was working with a customer whose AAD sync was missing some users. I’d set it up a couple of months previously and it had been working well, but clearly something had gone awry.

Microsoft knowledge base article 2643629 describes why one or more objects don’t sync when using the Azure Active Directory Sync tool but my problem turned out to be a lot more fundamental.

I checked the Synchronisation Service Manager (miisclient.exe) and found that there hadn’t been a sync for over three weeks. Then I looked in the Task Scheduler on the AAD Sync server; the Scheduled Task was still there and it had last run a couple of hours previously. Digging a little deeper and looking at the history though, showed that the task had been failing for a few weeks (every 3 hours), because a previous task was still running.

So, I restarted the server (to clear out long-running processes) and ran the sync, then watched in the Synchronisation Service Manager to check that it started logging the synchronisation events again. Once the sync was completed (with lots of changes, as expected), I changed the timeout on the scheduled task to 2 hours so it should always end before the next begins.

A delta sync sorted most of the issues, but I did need to force a full sync to get all of the missing users up to the cloud, by running directorysyncclientcmd.exe initial.

Incidentally, we’re all used to running idfix.exe before implementing directory synchronisation but occasionally admins create problem objects afterwards too… somehow an account had crept into scope that had a space in the username and no UPN. Predictably, AAD sync didn’t like that and my customer was being emailed after each sync with a notification that AAD Sync was:

Unable to update this object in Azure Active Directory, because the attribute [Username], is not valid. Update the value in your local directory services.

As Joran Markx explains, you can control who the identity synchronisation error reports are sent to by editing the technical contact for the tenant.


Viewing Active Directory object updates with RepAdmin

A couple of weeks back, I found myself having to investigate what had caused an Active Directory user account to be updated. We could see the last modified time on the Object tab for a user account in Active Directory Users and Computers (dsa.msc) and it’s also available using PowerShell.

What I really wanted to know though, was what attribute(s) on the object had changed.

It turns out that viewing Active Directory object updates is remarkably simple – even as a normal (non-admin) user. First of all you need to know the distinguished name (DN) for the object. If you don’t have access to any administrative tools then the following script might be useful (taken from the “Hey, Scripting Guy!” blog):

Set objSysInfo = CreateObject("ADSystemInfo")
strUserName = objSysInfo.UserName

Set objUser = GetObject("LDAP://" & strUserName)
strOUName = objUser.Parent

Set objOU = GetObject(strOUName)
Wscript.Echo objOU.distinguishedName

If you run this script, it will display something like:


I also needed to know the name of a domain controller – that’s easy as the %logonserver% environment variable will provide the information.

Armed with that information, I could then use the repadmin.exe command to find out some more information about the user object. I did need to install the Remote Server Administration Tools (RSAT) for Windows 8.1 to get repadmin on a client machine (there are similar RSAT packages for Windows 7 and Windows 10 too). Specifically, the command I used was repadmin.exe /showobjmeta servername "CN=Mark Wilson,OU=Users,OU=companyname,DC=domainname,DC=tld"

The resulting output contains all sorts of information, including which domain controller made the update for each attribute, at what date/time, to which version, and with which unique serial number (USN). So, for example, I can see the date when my password was last set (from unicodePwd, ntPwdHistory, and pwdLastSet) and that it was version 6.  There’s more information in Rick Bergman’s Ask Premier Field Engineering (PFE) post on how to track the who, what, when and where of Active Directory attribute changes.

Manually removing servers from an Exchange organization

I’m starting this blog post with a caveat: the process I’m going to describe here is not a good idea, goes against the advice of my colleagues (who have battle scars from when it’s been attempted in a live environment and not gone so well) and is certainly not recommended. In addition, I can’t be held responsible for any unintended consequences of following these steps.

Notwithstanding the above, I found myself trying to configure the Exchange Hybrid Configuration Wizard (HCW) in a customer environment, where the wizard failed because it was looking for servers that don’t exist any more.

I had two choices:

  1. Recover the missing Exchange servers with setup.exe /m:RecoverServer, then uninstall Exchange gracefully (for 12 servers!).
  2. Manually remove the servers using ADSI Edit.

I explained the situation to my customer, who discussed it with his Exchange expert, and they directed me to go for option 2 – this was a test environment, not production, and they were prepared to accept the risk.

Fearing the worst, I made a backup of Active Directory, just in case. This involved:

  1. Installing the Windows Server Backup Command Line Tools feature on the domain controller.
  2. Running wbadmin start systemstatebackup -backuptarget:driveletter:
  3. Sitting back and waiting for the process to complete.

With a backup completed, I could then:

  1. Run ADSI Edit.
  2. Open the configuration naming context.
  3. Navigate to CN=Servers,CN=Exchange Administrative Group (FYDIBOHF23SPDLT),CN=Administrative Groups,CN=organizationname,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=domainname,DC=tld
  4. Delete the records for the servers that no longer exist.
  5. Restart each of the remaining Exchange servers in the organisation in turn.
  6. Check the server list in ECP.

(Incidentally, FYDIBOHF23SPDLT is “Caesar’s Cipher” for EXCHANGE12ROCKS).

Murat Yildirimoglu’s Windows IT Pro article entitled “How to Uninstall a Stubborn Exchange Server” goes into more detail, including completely removing an Exchange organisation from Active Directory, should that be required (Christopher Dargel covers that too).

The process seemed to work but the danger of manually removing servers from an Exchange organization like this is the potential side effects of “unknown unknowns” (which you can be sure won’t surface immediately). It did let me progress to the next stage of the HCW though. More on that in a future blog post…

Reconfiguring Azure AD Sync – rip and replace!

I had an interesting learning experience recently, whilst working with a customer to implement some Microsoft Online services.

They have an existing AAD Sync installation, although from time to time that stops working when Microsoft changes the IP addresses of the servers that are needed for synchronisation. This is not a recommended configuration – but the reasons why are well-described in David Ross’ post on using a proxy with Azure AD Sync Services. To limit the number of IP addresses in their firewall and router configurations, this customer places hosts file entries on the Azure AD Sync server, meaning that Azure AD Sync only uses two IP addresses to find the hosts:

Microsoft publishes a full list of Office 365 URLs and IP addresses, together with an RSS feed for changes.

Anyway, to cut a long story short, my customer created a test environment by cloning existing servers into Azure IaaS. I ran IdFix against test directory objects, changed the UPN on the user accounts to match the domain we had associated with Office 365 ( and ran the Microsoft Azure Active Directory Sync Services tool (directorysynctool.exe) to set Azure AD Sync up with the new, test Office 365 tenant. Then I sat back and waited for the changes to sync.

To my horror, I found that the changes didn’t sync to the test Office 365 tenant, but to production! Running miisclient.exe confirmed that the original connectors were in place and had had not been changed by re-running the Directory Sync Services tool.

Unfortunately, because the production AAD Sync server was unable to connect to Azure (due to IP address changes…), we couldn’t force a sync from that server to overwrite the stale directory information, which meant late night working was needed to get emergency changes in place and restore service.

Once the production AAD Sync was up and running again, the live directory data was re-synced to Azure AD and services that relied on this (Intune-managed mobile devices were the obvious ones) started working again.

As expected, the sync with the correct directory over-wrote the changes from the stale directory and the login names for those users that had changed to (because their UPN from the test domain was not valid in the production tenant) reverted to the correct UPNs (which have verified domains in the tenant).

In the cold light of day, I realised that the issue was not caused by me – the only reason synchronisation from the test environment hadn’t over-written the live directory sooner was that the test AAD sync server didn’t have Internet access and then I’d disabled the scheduled task whilst running the Directory Sync Services tool. Once it was enabled it simply did its job – but the key learning point for me is that reconfiguring Azure AD Sync is not as simple as re-running the Directory Sync Services tool and supplying the necessary details – it really needs to be ripped out and run from scratch because directly editing the connectors is unsupported:

Microsoft does not support modification or operation of the Directory Sync tool outside of those actions formally documented.  […]  Unsupported actions include:

  • Opening the underlying FIM Sync Engine to modify Connector configuration
  • Manually controlling the frequency and/or ordering of Synchronization Run Profiles or changing the attributes that are synchronized to the cloud.

Any of these actions may result in an inconsistent or unsupported state of the Directory Sync tool and as a result, Microsoft cannot provide technical support for such deployments / usage of the tool. Filtering configurations applied to your directory synchronization instance aren’t saved when you install or upgrade to a newer version. If you are upgrading to a newer version of directory synchronization, you must re-apply filtering configurations after you upgrade, but before you run the first synchronization cycle.

Bulk changing Active Directory UPNs from PowerShell

As part of my current Office 365 project, I needed to prepare an on-premises Active Directory for synchronisation with Azure AD. This was a test environment that had been created by taking a copy of the production directory, so I had thousands of users – but all with incorrect user principal names (UPNs) that needed to be changed to a new value @test.domainname.tld.

I added the new UPN to the forest in Active Directory Domains and Trusts, then ran the following PowerShell for each OU that contained users I was going to synchronise with Azure AD (discovered via David O’Brien):

Get-ADUser -Filter * -SearchBase 'OU=Employees,OU=Users,OU=CompanyName,DC=DomainName,DC=tld' -Properties userPrincipalName | foreach { Set-ADUser $_ -UserPrincipalName "$($_.samaccountname)@test.domainname.tld"}

The command failed when I ran it on the domain controller (as did the script I originally tried) but when I used PowerShell on another server that was a member of the domain (my Azure AD sync server), it worked. This forum post suggests that it can run locally if you use the -server parameter but I haven’t tried that.  Just be sure to run Import-Module ActiveDirectory first, or else the *-ADUser commands won’t be available.

Choosing an Office 365 identity model (when to use ADFS)

At the time of writing, Microsoft Office 365 has the ability to work with three identity models:

  • Cloud identity (stored in Microsoft Azure Active Directory).
  • Synchronised identity (a copy of the objects from an on-premises Active Directory is made in Microsoft Azure AD), optionally with synchronised password hashes.  This is also known as same sign on (not single sign on as there are still two separate objects, albeit two objects that are kept synchronised).
  • Federated identity, using a federation service (such as Active Directory Federation Services, but others are supported) to authenticate users in an on-premises directory following which authorisation can be granted to Office 365 resources. This is also known as single sign on.  In this instance, directory synchronisation is still used to populate the Azure AD with user objects, although authentication happens on-premises.

Whilst the majority of small businesses will be fine with cloud identities, many of my conversations with enterprise customers start off in the directory synchronisation space. Generally, synchronisation is performed using the Office 365 DirSync appliance (a customised version of Forefront Identity Manager) although, more recently a new tool (Azure AD Sync) has been released that will eventually replace DirSync.  At the time of writing the main difference is that Azure AD Sync supports multiple forests (DirSync is a single forest solution) but it doesn’t support password synchronisation (still a major advantage for DirSync).

In general, the approach I recommend is to choose the simplest model for the organisation’s needs. The cloud identity model can work well when there is no on-premises directory service or there is no requirement to integrate; synchronised identity is the most commonly used (assuming there is an existing Active Directory) but sometimes federation is required:

  1. If there is an existing ADFS infrastructure.
  2. If a third party federated ID provider is in use.
  3. If Forefront Identity Manager 2010 is in use (which does not support password synchronisation).
  4. If there are multiple on-premises Active Directory forests (although Azure AD sync may negate this requirement).
  5. If smart cards or other third-party multi-factor authentication solutions are in use (Azure AD does have an MFA capability, although there are some restrictions on its use).
  6. If custom hybrid apps or hybrid search are in use (SharePoint).
  7. If a hybrid Lync solution is in use (i.e. placing users with enterprise voice capabilities on premises and those that don’t need voice in Lync Online, sharing the same SIP namespace).
  8. For self-service password reset via a web service (only administrators have self-service password reset in Office 365).
  9. If there is a requirement to audit logins and/or immediately disable accounts.
  10. If there is a requirement for single sign-on (i.e. accessing Office 365 workloads with the same user credentials as on-premises).
  11. If there is a requirement to restrict client logins by time or location.
  12. If the organisational security policy prevents the synchronisation of password hashes to Azure AD.

On a related topic, the Microsoft Online Services Sign-in Assistant (MOSA) for IT Professionals only exists to simplify the user experience (handling tokens, etc.) and is generally not required with modern versions of Office. Administrators using PowerShell may still need it though.

Finally, if ADFS is down, there is no way for users to authenticate. For that reason, federated infrastructure needs to be highly available (e.g. multiple ADFS proxies and multiple ADFS servers).  One method that’s starting to be commonly recommended is an “ADFS safety net”, using DirSync as a fall back (it’s possible to move between identity models on demand) but obviously that’s only an option if your organisation’s security policy allows the synchronisation of identities (including password hashes to minimise the impact on end users).

For reference, the PowerShell commands are:

Convert-Msol-DomainToStandard -DomainName domainname.tld -SkipUserConversion $true
Convert-Msol-DomainToFederated -DomainName domainname.tld

Set-Msol-DomainAuthentication -Authentication Managed -DomainName domainname.tld
Convert-Msol-DomainToFederated -DomainName domainname.tld

Credit is due to Michel de Rooij (@mderooij) for the ADFS safety net tip.

Confusion over accounts used to access Microsoft’s online services

I recently bought a new computer, for family use (the Lenovo Flex 15 that I was whinging about the other week finally turned up). As it’s a new PC, it runs Windows 8 (since upgraded to 8.1) and I log in with my “Microsoft account”. All good so far.

I set up local accounts for the kids, with parental controls (if you don’t use Windows Family Safety, then I recommend you do! No need for meddling government firewalls at ISP level – all of the major operating systems have parental controls built in – we just need to be taught to use them…), then I decided that my wife also needed a “Microsoft account” so she could be registered as a parent to view the reports and over-ride settings as required.

Because my wife has an Office 365 mailbox, I thought she had a “Microsoft account” and I tried to use her Office 365 credentials. Nope… authentication error. It was only some time later (after quite a bit of frustration) that I realised that the “Organization account” used to access a Microsoft service like Office 365 is not the same as a “Microsoft account”. Mine had only worked because I have two accounts with the same username and password (naughty…) but they are actually two entirely separate identities. As far as I can make out, “organization accounts” use the Windows Azure Active Directory service whilst “Microsoft accounts” have their heritage in Microsoft Passport/Windows Live ID.

Tweeting my frustrations I heard back from a number of online contacts – including journalists and MVPs – and it seems to be widely accepted that Microsoft’s online authentication is a mess.

As Jamie Thomson (@JamieT) commented to Alex Simons (@Alex_A_Simons – the Programme Director for Windows Azure Active Directory), if only every “organization account” could have a corresponding “Microsoft account” auto-provisioned, life would be a lot, lot simpler.