Multi-Factor Authentication in Office 365 (Part 2)

wp_ss_20140521_0001Multifactor Authentication is a must-have for services based in the cloud, especially for accounts with administrative purposes. We have already covered what Office 365 Multifactor Authentication is and how to configure it in Office 365 tenants with the Office 365 admin center, and we briefly showed the end user experience. Now we will look at how we can use the Azure Active Directory Module for Windows PowerShell to configure Office 365 authentication with MFA.

Azure Active Directory Module for Windows PowerShell (AADMPS) enables organizations to not only configure MFA for existing end users who use PowerShell, but also enhance their current provisioning process with MFA options. By pre-configuring MFA, administrators can prevent end users from having to go through the initial MFA setup process and use their currently configured mobile phone or office number for verification.

Read the full article over on SearchExchange

Multi-Factor Authentication in Office 365 (Part 1)

Multi-Factor AuthenticationMulti-Factor Authentication identifies an end user with more than one factor. Authentication is based on something you know, such as your password; something you have, such as a security token or smart card; or something that’s a physical characteristic of who you are, such as biometrics. By creating an additional factor on top of the password, identity is better protected. Multi-Factor Authentication is seen as a must-have for cloud-based services, especially for administrative types of accounts.

In this first tip on SearchExchange, I explain how you can configure Multi-Factor Authentication in Office 365, discuss the so-called contact methods, explain app passwords for non-MFA applications as well as show the MFA end user experience.

Read the full article over on SearchExchange

Exchange can’t start due to misconfigured AD sites

Recently, a customer had issues with their Exchange server which didn’t start properly after rebooting. After checking out the Eventlog, I noticed the it was full of messages, generated by all services. The most interesting events were the ones generated by MSExchange ADAccess:

MSExchange ADAccess, EventID 2141
Process STORE.EXE (PID=2996). Topology discovery failed, error 0x8007077f

MSExchange ADAccess, EventID 2142

Process MSEXCHANGEADTOPOLOGYSERVICE.EXE (PID=1760). Topology discovery failed, error 0x8007077f

Also, the results of the active directory discovery process generated every 15 minutes, which are normally logging in event 2080, “Exchange Active Directory Provider has discovered the following servers with the following characteristics”, was missing.

Note that because the system could start the Microsoft Exchange Active Directory Topology service (until it failed and is restarted by dependent services), Exchange’s other services were also triggered, leading to almost indefinitely restarting services as configured in their corresponding service recovery actions sections.

Now, since I had connected to a domain controller using an RDP session from my client, and I was able to connect to port 389 (Global Catalog) from Exchange using LDP, so communications looked ok. Then, I switched to Active Directory Sites and Services:

image

As you can see from the shot, here was a potential cause of the problem. First, there was a site without domain controllers. Second, there were no subnets defined. So, in this situation, it is undetermined in which site Exchange is located.

When a system can’t be determined to which site a computer belongs, the function DSGetSiteName, used to retrieve the current site, returns an error 1919 0x77f (ERROR_NO_SITENAME). Consequently, the Exchange Active Directory discovery process fails and eventually Exchange fails. You can inspect the current discovered site using nltest /dsgetsite or by having a peek in the registry at HKLM\System\CurrentControlSet\Services\Netlogon\Parameters\DynamicSiteName.

Now, to solve the situation we have three options:

  1. Making the site association static using a registry key, which isn’t a best practice.If you must, set registry key HKLM\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters\SiteName (REG_SZ) to the desired site name;
  2. Adding proper subnet definitions;
  3. Remove the empty site definition.

It turned out the empty site was a place holder for a future site, so we went with the option of adding proper subnet definitions. After adding subnet definitions, like you normally should when working with multiple sites, including the scopes where the Exchange servers and domain controllers were located, and associating it with the main site, things started working again.

Note that the NetLogon service determines site association membership at startup and every 15 minutes. The Microsoft Exchange Discovery Topology service maintains this information by caching the information in the msExchServerSite attribute of the Exchange server object, in order to reduce load on active directory and DNS. Therefor, you might need to wait or restart Microsoft Exchange Discovery Topology  if you want to renew site association membership.

Windows Server 2012 RC Version and Levels

A quick post on the possible schema version and functional levels introduced with the release of Windows Server 2012 RC.

The schema version of a Windows Server 2012 Release Candidate forest is 56 (was 52 in the Windows “8” Beta). For more information on Active Directory schema versions and how to read this information, consult the AD Schema Versions page here.

Also, the msDS-Behavior-Version attribute of Windows Server 2012 domain controllers is set to 5, which is the same number as the Windows “8” beta version number. For more information on Active Directory Functional Levels and how to read this information, consult the AD Functional Levels page here.

Retrieving DCs functional capabilities

While constructing a page for the forest and domain functional levels, and the maximum functional level for domain controllers, I wanted to show an example of how to retrieve this Active Directory attribute for all domain controllers. You could for example incorporate this in your automated procedures to check for any Windows 2003 servers and take further actions when needed.

The script is below. It outputs object so you use the pipe for further processing. For information on the possible values for msDS-Behavior-Version check out the new AD Functional Levels page here.

#--------------------------------------------------------------------------------
# Name         : Get-DCMSDSBehaviorVersion.ps1
# Created By   : Michel de Rooij
# E-mail       : michel@eightwone.com
# Date         : 20120307
# Source       : http://eightwone.com
# Version      : 1.0
#
# THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK
# OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.
#--------------------------------------------------------------------------------

$RootDSE= [ADSI]'LDAP://RootDSE'
$objSearchRoot= New-Object DirectoryServices.DirectoryEntry( "LDAP://"+ $RootDSE.configurationNamingContext)
$objSearch= New-Object DirectoryServices.DirectorySearcher
$objSearch.SearchRoot= $objSearchRoot
$objSearch.Filter= "(objectClass=nTDSDSA)"
$objSearch.SearchScope = "SubTree"
$Results= @()
$objSearch.FindAll() | ForEach {
    $objItem = $_.getDirectoryEntry()
    $obj= New-Object PSObject -Property @{
        Servername= $objParent = $objItem.psbase.parent.DNSHostName.ToString()
        MSDSBehaviorVersion= $objItem.Get("MSDS-Behavior-Version")
    }
    $Results+= $obj
}
$Results

Note that if you have over 1000 domain controllers, you need to set the $objSearch.Pagesize, e.g. 1000. It may also encounter problems in forests with multiple roots.

Comparing Active Directory Permissions

Every now and then you might be required to compare Active Directory account permissions. When it concerns one or few accounts, you could do the manual side-by-side comparison using Active Directory and Computers. However, when you need to check multiple accounts this task becomes tedious.

Now you could follow the practice laid out by Exchange fellow Andy Grogan here,  generating permissions output using Quest Active Roles and comparing the textual output with a comparison utility like WinMerge or WinDiff. But you can also perform this comparison using PowerShell’s Compare-Object cmdlet, which I’ll show you here.

For this task we’re going to use the Quest AD extensions (Active Roles), which you can download here. Install these extensions on a domain-joined system where PowerShell is already installed. After installation, start the ActiveRoles Management Shell and enter the following, where IdA and IdB are the Identities of the objects you want to compare:

$a= Get-QadPermission <IdA> -Inherited -SchemaDefault
$b= Get-QadPermission <IdB> -Inherited –SchemaDefault

Now $a and $b contain the permission sets of both objects. Next, we’re going to utilize compare-object to compare these two sets. When we use Compare-Object $a $b you get the following output:

image

Not quite helpful this output but it isn’t unexpected. Since we’re comparing two object sets compare-object generates a result with objects. We can make this more readable by specifying the PassThru parameter so we can post-process these objects, like displaying certain fields using the Format-Table cmdlet, e.g.

Compare-Object $a $b -PassThru | ft SideIndicator,AccountName,Rights,Source,ApplyTo

image

Presto! The SideIndicator  is included to see in which set the attribute is contained, e.g. “<=” means the element is contained in the 1st specified (reference) object and “=>” means its is contained in the 2nd (difference) object.

If you want to include equal objects in the output as well, add the IncludeEqual parameter to the Compare-Object cmdlet.

Active Directory Migration Tool 3.2

At last, the Active Directory Migration Tool (ADMT) 3.2 was released to public. ADMT can be used to migrate and reorganize objects across in inter-forest (cross-forest) or intra-forest scenarios.

The previous version, ADMT 3.1, dates back to July, 2008 and is supported only on Windows Server 2008, but not R2. With the release of R2 this lead to added  complexity because projects needed to introduce a different OS in their environment.

The new 3.2 version of ADMT only runs on Windows Server 2008 R2, but not on earlier versions. As you can also see from the table below, the new ADMT version requires Windows Server 2003 domain functional level in both the source and the target domain:

ADMT
Version
OS
Support
Source Domain
Target Domain
2000 2003 2008 2008
R2
2000 2003 2008 2008
R2
3.1 2008 YES YES YES YES YES YES
3.2 2008 R2 YES YES YES YES YES YES

You can download ADMT 3.2 here. The updated ADMT Guide: Migrating and Restructuring Active Directory Domains can be found here.

Note that ADMT uses Password Export Server (PES) which is currently still at version 3.1. Be advised that this version of PES isn’t supported on Windows Server 2008 R2, so I expect an update for PES as well. PES 3.1 can be downloaded here (x64) or here (x86).

Kerberos Max Token Size

Ok, not directly Exchange related but an issue I’d like to share. In one of my earlier articles you can read I’m working on on a project where we’ll be performing a cross-forest migration of accounts and Exchange mailboxes. Migrating the Active Directory user accounts is done using ADMT v3.1 with SIDHistory. No problem so far, until we noticed some migrated users weren’t receiving Group Policy Objects and experienced authorization errors from time to time. After identifying several users experiencing similar issues, we noticed the following common eventlog entries:

System eventlog (the number 3888 varied):

Event ID : 6
Source : Kerberos
The kerberos SSPI package generated an output token of size 3888 bytes, which was too large to fit in the 2e00 buffer buffer provided by process id 0. If the condition persists, please contact your system administrator.

The Application eventlog contained the following event:

Event ID : 1053
Source : UserEnv
Windows cannot determine the user or computer name. (). Group Policy processing aborted.

Turns out, Kerberos is the culprit. GPO processing aborted because their Kerberos information exceeded the maximum Kerberos token size. This problem may occur when users belong to (too) many groups (.. don’t ask). In addition, memberships coming from SIDhistory are also added to the token, roughly doubling numbers.

As MS KB articles 263693 and 327825 suggest, we raised the MaxTokenSize limited to 65535 (0xFFFF) in the following registry location (if the value is not present, create it as REG_DWORD):

HKLM\SYSTEM\CurrentControlSet\Control\LSA\Kerberos\Parameters\MaxTokenSize

After a restart, all problems were gone. This isn’t a standard GPO setting; when required, you need to create an .adm GPO template yourself which is described in KB article 938118. Hope you’ll find this information useful to keep in mind when performing your ADMT scenarios at clients with excessive group usage.

ForeFront Identity Manager 2010 RTM

By now you’ve probably already heared ForeFront Identity Manager 2010 went RTM on March 2nd. FIM 2010 is the successor to ILM, the Identity Lifecycle Manager. FIM is an solution to manage identities and credentials in heterogeneous environments. It contains functionality for user (de)provisioning, password synchronization, group management, self-service and workflow-like applications. So for instance, FIM can enable organizations to automatically create an Active Directory user with an Exchange mailbox with all the proper settings when a new employee has been entered into the HRM system (or disabled or removed when the employee leaves the organization, depending on requirements).

You can download the trial here. More information on the FIM portal here.

Cross-Forest Mailbox Move

Note: This is part 1; part 2 can be found here.

Currently I’m working with Johan Veldhuis on a project where we’ll be moving mailboxes from Exchange 2003 to Exchange 2010. Accounts and mailboxes will be migrated from forest to forest and to make things more interesting, the account migration is isolated from the mailbox migration. In other words, we start with a single forest after which we’ll create a account/resource forest setup from where we’ll consolidate things again. The account/resource forest setup is not completely by the book as the accounts in the resource forest won’t be disabled. This is because ActiveSync devices will be migrated at a later stage; this means they can use their existing authentication information.

Note: In the remainder of this article the following variables are used:

  • olddomain.nl is the source forest with Exchange 2003;
  • newdomain.com is the new forest with Exchange 2010;
  • Jan Test is our to be migrated test user with User ID jtest;
  • source.nl is an e-mail domain for which Exchange 2003 is authoritative;
  • target.com is an e-mail domain for which Exchange 2010 is authoritative.

The starting point of this blog is the situation where both forests olddomain.nl and newdomain.com are up and running. There is a trust between olddomain.nl and newdomain.com, ADMT and the Password Export Server are configured and running properly. This means we can successfully migrate user accounts from olddomain.nl to the new forest newdomain.com; the user’s mailbox will remain on Exchange 2003 in olddomain.nl.

Here is where the first problem was encountered. The Active Directory schemas mismatch, so ADMT will only migrate a basic set of attributes. This means that although newdomain.com has Exchange attributes, these won’t be migrated. Also, to be able to use the mailbox properly from their newdomain.com account, we need to add mailbox permissions for the newdomain.com account. For this purpose we created a post-migration script which adds Full Mailbox Access and External Account permissions to the mailbox for the newdomain.com account. After that we have reached an intermediary state, with accounts in newdomain.com and resources (mailboxes) in olddomain.nl; Users will log on using an account from the newdomain.com account forest and access their mailbox in the olddomain.nl resource forest.

The next phase will be migrating Exchange 2003 mailboxes from olddomain.nl to Exchange 2010 mailboxes in newdomain.com. Microsoft provides a nice TechNet article (633491) on how to prepare mailboxes for cross-forest mailbox move requests. The article also links to a (sample) PowerShell script, part of ILM 2007 SP1, located here. The script, Prepare-MoveRequest.ps1, should prepare the target forest for mailbox move request. Unfortunately, we couldn’t get it working properly.

First, the script complained it couldn’t find the specified Identity in the target forest. This was odd; the account is present, it was created by ADMT. Diving into the code it looks for the identity in various attributes:

filterParm = “(& (objectClass=user)” +
”   ( (| (mailnickname=$escapedIdentity)” +
”        (cn=$escapedIdentity)” +
”        (proxyAddresses=SMTP:$escapedIdentity)” +
”        (proxyAddresses=smtp:$escapedIdentity)” +
”        (proxyAddresses=X500:$escapedIdentity)” +
”        (proxyAddresses=x500:$escapedIdentity)” +
”        (objectGUID=$escapedIdentity)” +
”        (displayname=$escapedIdentity))))”

$srcObject = findADObject $srcdc $filterParm

No matter what we tried, no match. Odd. Also, the script contains code which creates objects when it determines it needs to and there’s no switch to turn this behaviour off. That switch would be nice, because the last thing we want is to end up with hundreds of mail-enabled user objects when there are already user account objects present. Since we had little time to debug and fix the script, we decided to prepare the target account in newdomain.com ourselves. I took a script from one of my earlier projects (VB), which I created for similar merger / split scenarios in the past, and checked it against the information in the TechNet article mentioned earlier. In the end we had a script which transforms users into mail-enabled users as follows:

  1. Copy the following atributes from the account in olddomain.nl to the account in newdomain.com: mail, mailNickname, msExchMailboxGuid, proxyAddresses;
  2. Adds the LegacyExchangeDN attribute from olddomain.nl account as an X500 address to the account in newdomain.com;
  3. Sets msExchRecipientDisplayType to -2147483642;
  4. Sets msExchRecipientTypeDetails to 128;
  5. Sets targetAddress in newdomain.com to the value of mail attribute in the olddomain.nl;
  6. Adds a constructed e-mail address (e-mail account olddomain.nl + @ + new e-mail domain, e.g. j.test@target.com) to the proxyAddresses in newdomain.com;
  7. Sets legacyExchangeDN on the new account in newdomain.com to “/o=<ORG>/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=<CN>”, where <CN> is the cn of the account.

This is more or less the same as the Prepare-MoveRequest.ps1 should do, but this one worked like expected. Note that the last three actions are important for getting the move request to work. The targetAddress should be set properly, because new-moveRequest will set the target Address of the olddomain.nl account to the primary SMTP address of the newdomain.com account. LegacyExchangeDN and the proxyAddress should be added because new-moveRequest uses these for lookup and matching (I assume, because we will also will specify the identity itself). The proxyAddress e-mail address for which Exchange 2010 in newdomain.com is authoritative will be promoted to primary SMTP e-mail address.

Now, after preparing the newdomain.com account and transforming it into a mail-enabled user, we can use new-moveRequest to transfer the mailbox from Exchange 2003 to Exchange 2010:

$cred = get-credential
new-moverequest -identity <userid> -RemoteLegacy -TargetDatabase “<Mailbox Database Name>” -RemoteGlobalCatalog dc.olddomain.nl -RemoteCredential $cred -TargetDeliveryDomain <target.com>

An explanation:

  • We need to specify RemoteLegacy because the source forest isn’t Exchange 2010;
  • TargetDatabase identifies the target database;
  • Using RemoteGlobalCatalog we specify a GC from the remote forest;
  • With RemoteCredential, in combination with get-credential, is used to prompt for credentials and use them in the cmdlet;
  • TargetDeliveryDomain specifies the external e-mail domain that is used to set the targetAddress in the source forest, so normally this should be an e-mail domain for which the source forest isn’t and the target forest is authoritative.

Presto! This is what the objects look like after performing the new-moverequest:

olddomain.nl
cn=Jan Test
mail=jtest@target.com
legacyExchangeDN=/o=<ORG>/ou=First Administrative Group/cn=Recipients/cn=jtest88083336
mailNickname=jtest
proxyAddresses=X500:/o=<ORG>/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=Jan Test;
smtp:J.Test@source.nl;
SMTP:jtest@target.com;
X400:c=NL;a= ;p=<org>;o=Exchange;s=Test;g=Jan;;
targetAddress=SMTP:jtest@target.com

newdomain.com
cn=Jan Test
mail=jtest@target.com
legacyExchangeDN=/o=<ORG>/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=Jan Test;
mailNickname=jtest
proxyAddresses=smtp:jtest@newdomain.com
;SMTP:jtest@target.com;X400:C=NL;A= ;P=<org>;O=Exchange;S=Test;G=Jan
;smtp:J.Test@source.nl
;smtp:J.Test@target,com
;X500:/o=<ORG>/ou=First Administrative Group/cn=Recipients/cn=jtest88083336
targetAddress=SMTP:jtest@target.com

Notice that new-moveRequest adds a random number “88083336” to legacyExchangeDN in olddomain.nl and to X500 in newdomain.com. This is to promote the newdomain.com account for legacyExchangeDN usage and enables mailflow from the old olddomain.nl to newdomain.com when replying on old e-mail.

Update: Also worth noting is we an additional challenge because the source domain name equaled their e-mail namespace, which they want to keep using during and after the migration. Therefor we had to introduce a bogus local namespace for which the Exchange 2003 becomes authoritative and 2010 is not. We can use recipient policies to stamp this address to mail-enabled objects and by creating a connector from Exchange 2010 to Exchange 2003 using this namespace, we can route e-mail from migrated users to non-migrated users.

I hope this information is useful. For more information on new-moveRequest for cross-forest moves, check here. When you have questions, post them in the comments below or send me an e-mail.