Connecting to Office 365/Exchange

powershellAlmost 3 years ago, I wrote an article on how to enhance the PowerShell Integrated Scripting Environment, or ISE. That seemed adequate for the Exchange admin back then, who mostly connected their PowerShell session to their his on-premises environment, and perhaps occasionally a bit of Exchange Online.

Fast forward to 2015, most modern Exchange administrators not only require a connection – if any – to their Exchange on-premises environment, but likely to one or more of the Office 365 services as well. This includes Exchange On-Premises, Azure Active Directory, Exchange Online Protection and perhaps even Skype for Business Online, SharePoint Online, Azure Rights Management Services or Compliance Center.

All these service use a different PowerShell session, use a different endpoint FQDN, and sometimes even require a locally installed PowerShell module. Likely common denominator is the credential used to access each of these services. So, tired of re-entering my credentials every time when switching from Exchange Online to Exchange Online Protection, I created a script with a set of functions to allow me connect to each individual Office 365 service or Exchange Online:

  • Connect-AzureAD: Connects to Azure Active Directory
  • Connect-AzureRMS: Connects to Azure Rights Management
  • Connect-ExchangeOnline: Connects to Exchange Online
  • Connect-SkypeOnline: Connects to Skype for Business Online
  • Connect-EOP: Connects to Exchange Online Protection
  • Connect-ComplianceCenter: Connects to Compliance Center
  • Connect-SharePointOnline: Connects to SharePoint Online
  • Get-Office365Credentials: Gets Office 365 credentials
  • Connect-ExchangeOnPremises: Connects to Exchange On-Premises
  • Get-OnPremisesCredentials: Gets On-Premises credentials
  • Get-ExchangeOnPremisesFQDN: Gets FQDN for Exchange On-Premises
  • Get-Office365Tenant: Gets Office 365 tenant name (SharePoint)

Note that functions and credentials used in the script are global, and in principle only need to be entered once per shell or ISE session. If you need different credentials, call Get-Office365Credentials again. User interaction is a very basic Read-Host, but it does the job.

Requirements
During initialization, the script will detect the modules which are required for certain Office 365 services. When not installed, it will notify you, and provide a link where to obtain the PowerShell module. The related Connect function will not be made available. The Azure Active Directory module also requires the Microsoft Online Sign-In Assistant to be installed. Needless to say, PowerShell is required to run this script, which is tested against version 4 (but should work with 3)

Usage
The functions are contained in a script called Connect-Office365Services.ps1. You can call this script manually from your PowerShell session to make the functions available. However, more convenient may be to have them always available in every PowerShell or ISE session. To achieve this, you need to edit your $profile, which is a script which always starts when you start a PowerShell or ISE session. By default this file does not exist and you need to create it, including the path. Also note that the files for PowerShell and ISE are different, Microsoft.PowerShell_profile.ps1
and Microsoft.PowerShellISE_profile.ps1 respectively.

Now, of course you can copy and paste the functions from the script file to your own $profile. Better is to call the script from your $profile, as this allows you to overwrite the Connect-Office365Services.ps1 with updates. To achieve this, assume you copied the Connect-Office365Services.ps1 in the same location as your $profile, for example C:\Users\Michel\Documents\WindowsPowerShell. You can then make PowerShell and ISE call this script by adding the following line to the $profile scripts:

& “$PSScriptRoot\Connect-Office365Services.ps1”

Now when you start a PowerShell session, you might see the following:

image

This shows the Microsoft Online Sign-In Assistant and Azure Active Directory PowerShell module is available, and related connect functions should be available.

When you load the script from ISE, it will show something similar. However, it will also show ISE is detected and make all functions available through the Add-On menu:

image

Notes
Customize this script to your liking. For example, if you always want to connect to Azure Active Directory when connecting to Exchange Online, add Connect-AzureAD in the Connect-ExchangeOnline function, or when you always want to connect to a fixed FQDN for Exchange On-Premises, insert it in the script or – better – configure your $profile to predefine the FQDN, e.g. $global:ExchangeOnPremisesFQDN=’mail.contoso.com’.

Also, you may with to leverage prefixing the imported cmdlets so you can easily switch between Exchange On-Premises and Exchange Online. For example, you can then having something like Get-EXOMailbox and Get-EOPMailbox corresponding to Get-Mailbox in your Exchange Online or Exchange On-Premises within the same shell session. However, as with aliases, think of the ‘the next guy’ who may not have these prefixed cmdlets, and instructions or scripts may require adoption to work, etc. But if you insist, for more information on prefixing cmdlets when importing a PowerShell session, see here.

Windows 10
Be advised that when used with Windows 10 build 10525 or 10532, your PowerShell session might crash when connecting to certain services, e.g. Exchange Online Protection. Fellow Exchange MVP Tony Redmond wrote about this here, including a possible workaround. Windows 10 RTM does not have this issue.

Download / Revisions
You can download the script from the TechNet Gallery here. The TechNet Gallery page as well as the script contains revision information.

Feedback
Feedback is welcomed through the comments. If you got scripting suggestions or questions, do not hesitate using the contact form.

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.