Exchange Autodiscover – The Active Directory SCP

In a previous post I explained how you can use a SRV record to resolve certificate issues with Autodiscover when your Internal domain isn’t the same as your Email domain. This time, I’m going to explain how to fix things by making changes to Exchange and Active Directory that will allow things to function normally without having to use a SRV record or any DNS records at all, for that matter. But only if the computers that access Exchange are members of your Domain and you configure Outlook using user@domain.local. This is how Exchange hands out Autodiscover configuration URLs by default without any DNS or SRV records. However, if you have an Private Domain Name in your AD environment, which you should try to avoid when you’re building new environments now, you will always get a Certificate Error when you use Outlook because SSL certificates from third party CA providers won’t do private domains on SAN certificates anymore. To fix this little problem, I will first give you a little information on a lesser known feature in Active Directory called the Service Connection Point (SCP).

Service Connection Points

SCPs play an Important role in Active Directory. They are basically entries in the Active Directory Configuration Partition that define how domain based users and computers can connect to various services on the domain. Hence the name Service Connection Point. These will typically show up in one of the Active Directory tools that a lot of people overlook, but is *extremely* important in Exchange since 2007 was released, Active Directory Sites and Services (ADSS). ADSS is typically used to define replication boundaries and paths for Active Directory Domain Controllers, and Exchange uses the information in ADSS to direct users to the appropriate Exchange server in large environments with multiple AD Sites. But what you can also do is view and make changes to the SCPs that are set up in your AD environment. You do this with a feature that is overlooked even more than ADSS itself, the Services node in ADSS. This can be exposed by right clicking the Active Directory Sites and Services object when you have ADSS open, selecting view, then clicking “Show Services Node” like this:

ADSS - Services Node

Once you open the services node, you can see a lot of the stuff that AD uses in the back end to make things work in the domain. Our focus here, however, is Exchange, so go into the Microsoft Exchange node. You’ll see your Exchange Organization’s name there, and you can then expand it to view all of the Service Connection Points that are related to Exchange. I wouldn’t recommend making any changes in here unless you really know what you’re doing, since this view is very similar to ADSIEdit in that it allows you to examine stuff that can very rapidly break things in Active Directory.

Changing the Exchange Autodiscover SCP

If we look into the Microsoft Exchange services tree, you first see the Organization Name. Expand this, then navigate to the Administrative Group section. In any Exchange version that supports Autodiscover, this will show up as First Administrative Group (FYDIBOHF23SPDLT). If the long string of letters confuses you, don’t worry about it. That’s just a joke the developers of Exchange 2007 put into the system. It’s a +1 Caesar Cipher that means EXCHANGE12ROCKS when decoded. Programmers don’t get much humor in life, so we’ll just have to forgive them for that and move on. Once you expand the administrative group node, you’ll be able to see most of the configuration options for Exchange that are stored in AD. Most of these shouldn’t be touched. For now, expand the Servers node. This is the section that defines all of your Exchange servers and how client systems can connect to them. If you dig around in here. Mostly you just see folders, but if you right click on any of them and click Properties, you should be able to view an Attributes tab (in Windows 2008+, at least, prior to that you have to use ADSIEdit to expose the attributes involved in the Services for ADSS). There are lots of cool things you can do in here, like change the maximum size of your Transaction Log files, implement strict limits on number of databases per server, change how much the database grows when there isn’t enough space in the database to commit a transaction, and other fun things. What we’re focusing on here is Autodiscover, though, so expand the Protocols tree, then go to Autodiscover, as seen below.

autodiscover node

Now that we’re here, we see each one of the Exchange CAS servers in our environment. Mine is called Exchange2013 because I am an incredibly creative individual (Except when naming servers). Again, you can right click the server name and then select Properties, then go to the Attribute Editor tab to view all the stuff that you can control about Autodiscover here. It looks like a lot of stuff, right? Well, you’ll really only want to worry about two attributes here. The rest are defined and used by Exchange to do…Exchangey stuff (Technical term). And you’ll really only ever want to change one of them. The two attributes you should know the purpose of are “keywords” and “serviceBindingInformation”.

  • keywords: This attribute, as you may have noticed, defines the Active Directory Site that the CAS server is located in. This is filled in automatically by the Exchange subsystem in AD based on the IP address of the server. If you haven’t created subnets in ADSS and assigned them to the appropriate site, this value will always be the Default site. If you change this attribute, it will get written over in short order, and you’ll likely break client access until the re-write occurs. The *purpose* of this value is to allow the Autodiscover Service to assign a CAS server based on AD site. So, if you have 2 Exchange Servers, one in site A and another in site B, this value will ensure that clients in site A get configured to use the CAS server in that site, rather than crossing a replication boundary to view stuff in site B.
  • serviceBindingInformation: Here’s the value we are most concerned with in this post! This is the value that defines where Active Directory Domain joined computers will go for Autodiscover Information when you enter their email address as username@domain.local if you have a private domain name in your AD environment. By default, this value will be the full FQDN of the server, as it is seen in the Active Directory Domain’s DNS forward lookup zone. So, when domain joined computers configure Outlook using user@domain.local they will look this information up automatically regardless of any other Autodiscover, SRV, or other records that exist in DNS for the internal DNS zone. Note: If your email domain is different from your AD domain, you may need to use your AD domain as the email domain when configuring Outlook for the SCP lookup to occur. If you do not want to use the AD Domain to configure users, you will want to make sure there is an Autodiscover DNS record in the DNS zone you use for your EMail Domain.

Now, since we know that the serviceBindingInformation value sets the URL that Outlook will use for Autodiscover, we can change it directly through ADSS or ADSIEdit by replacing what’s there with https://servername.domain.com/Autodiscover/Autodiscover.xml . Once you do this, internal clients on the domain that use user@domain.local to configure Outlook will be properly directed to a value that is on the certificate and can be properly configured without certificate errors.

Now, if you’re a little nervous about making changes this way, you can actually change the value of the serviceBindingInformation attribute by using the Exchange Management Shell. You do this by running the following command:

get-clientaccessserver | set-clientaccessserver -autodiscoverserviceinternaluri “https://servername.domain.com/Autodiscover/Autodiscover.xml”

This will directly modify the Exchange AD SCP and allow your clients to use Autodiscover without getting certificate errors. Not too difficult and you don’t have to worry about split DNS or SRV records. Note, though, that like the SRV record you will be forcing your internal clients to go out of your network to the Internet to access your Exchange server. To keep this from happening, you will have to have an Internal version of your External DNS zone that has Internal IPs assigned in all the A records. There just is no way around that with private domain names any longer.

Final Note

Depending on your Outlook version and how your client machines connect, there is some additional configuration that will need to be completed to fully resolve any certificate errors you may have. Specifically, you will need to modify some of the Exchange Virtual Directory URLs to make sure they are returning the correct information to Autodiscover.

Avoiding Issues with Certificates in Exchange 2007+

For information, modern Active Directory Best Practices can help you avoid having trouble with certificate errors in Exchange. Go here to see some information about modern AD Domain Naming best practices. If you follow that best practice when creating your AD environment, you won’t have to worry so much about certificate errors in Exchange, as long as the Certificate you use has the Exchange Server(s) name listed. However, if you can’t build a new environment or aren’t already planning to migrate to a new AD environment in the near future, it isn’t worth the effort to do so when small configuration changes like the one above can fix certificate errors.

Advertisements

PowerShell Error Correction Functions

One of the more annoying things that you have to deal with in building scripts that accept input from users is error correction. Error correction ensures that users who are using a script that requires some input from them (the location of a file, a menu with numbered selections they have to choose from, etc.) can’t input incorrect information and get confused by the weird errors that PowerShell throws out. The reason this is such a pain is that it is very difficult to predict how someone can screw things up on your script. I can’t really give too much of a guide on how to predict this type of thing, since it depends heavily on what you’re doing with your scripts, but I can provide the world with a few canned functions that I created for a giant PowerShell based UI that I created for a client that allowed their non-PowerShell proficient admins to perform PowerShell only functions in Exchange. Use them as you wish by copying and pasting them into your own PowerShell scripts, and calling them appropriately in your code. Also note that some of these functions use other functions. If you want to use them, I recommend adding all of these functions to your script before doing so.

Checknull Function

This function checks input to make sure there is actually some stuff entered. You use the function by placing it in a variable. It would look something like this:

$value = checknull “Enter a number” “You didn’t enter anything. Try again”

This would cause a prompt to show up that says “Enter a Number.” If you hit enter without doing anything, it will fail, display “You didn’t enter anything. Try again” and re-prompt.

And here’s the function:

function checknull($prompt,$errormsg)
{
do{
$err = 0
$input = read-host “$prompt”
if ($input -like $null)
{
write-host “$errormsg”
$err = 1
}
}while ($err -eq 1)
return $input
}

IsNumeric function

This function checks if data that is input is a number or a string. You can occasionally break a PowerShell script that requires users to input numbers by using letters instead. This function checks an existing variable to determine whether it’s a number or a string of letters or a combination of both. It will only return a $true result if the variable is completely numeric. Using this is a bit tricky. But as an example, here is what you can do, in combination with the checknull function:

$value = checknull “Enter a number” “You didn’t enter anything. Try again”

$numeric = isnumeric $value
if($numeric -like $true)
{“Yep. That’s a number”}
else
{“That’s not a number”}

You can run that if you like and see what happens.

Here’s the function:

function isNumeric ($x)
{
try
{
0 + $x | Out-Null
return $true
}
catch
{
return $false
}
}

Checknum Function

This function checks to make sure an entered number is between a specific range as defined in the function call. You use this by entering it into a variable, just like the checknull function. It uses the isNumeric function to ensure that entered data is actually a number and not a letter. So it’s nested error correction (hurray). You use it like this if you wanted a user to enter a number between 1 and 5

$number = checknum “Enter a number between 1 and 5” 1 5

It will automatically re-prompt if the user enters something outside the range. I don’t think it will handle negative numbers, but you are welcome to try. Here’s the function.

function checknum ($prompt,$min,$max)
{
do{
$err = 0
$input = read-host $prompt -erroraction silentlycontinue
$num = isnumeric $input
if (($input -lt $min) -or ($input -gt $max) -or ($num -like $false))
{
write-host “Please enter a number between $min and $max”
$err = 1
}
}while ($err -eq 1)
return $input
}

CheckMailbox function

This function checks to see if a mailbox in Exchange 2007+ exists. You can use this to make sure a mailbox exists before performing some bulk action, or you can just use it as is to see if a mailbox exists. This is also a nested error correction function. To use it, simply enter checkmailbox “Enter a mailbox name”. Note that this function is not compatible with bulk operations. It can only handle one mailbox at a time. It will re-prompt the user until they enter a valid mailbox.

function checkmailbox ($prompt)
{
do {
$err = 0
$mailbox= checknull $prompt
#Check Moderator name entered for validity
try
{
get-mailbox $mailbox -erroraction stop | out-null
}
catch
{
write-host “$mailbox does not exist”
$err = 1
}
}while ($err -eq 1)
return $mailbox
}

CheckFile function

This function checks to see if a file path exists. Pretty self explanatory. Same rules as the checkmailbox function, same usage.

function checkfile ($prompt)
{
do{
$file = checknull “$prompt” “Please enter a valid File Name”
try
{
$err = 0
dir $file -erroraction stop | out-null
}
catch
{
write-host “$file does not exist.”
$err = 1
}
}while ($err -eq 1)
return $file
}

And that’s what I have so far. Feel free to comment and add your own error correction functions if you wish or link to your blog that contains them.

 

Removing Addresses from an Exchange 2007/2010/2013 Server

This is probably a rare issue, but something I’ve come across in my work. Occasionally an Exchange Administrator may need to remove an Email address domain (The part of the email address that comes after the @ sign). For instance, you may be in a situation where a portion of the users in an Exchange environment are migrated to a Cloud based email solution. This can be a little tricky because even if you remove the email address domain from your list of Accepted Domains in Exchange, the addresses may remain on users’ mailboxes. In this post, I’ll explain the process of removing email domains from an Exchange Server in the proper order.

Step 1 – Remove Address Policies that Use the Domain

Before you can actually remove an accepted domain from Exchange, you have to make sure there are no Address Policies that assign email addresses to users that utilize that accepted domain. In Exchange 2007 and 2010, you can do this by opening EMC (Exchange Management Console) and navigating to Organization Configuration>Hub Transport. Clicking the Address Policies tab will allow you to view the address policies in place. You should then remove any policies that define addresses based on the Email Address Domain you want to remove.

In Exchange 2013, you would open the Exchange Admin Center and navigate to Mail Flow>Email address policies, then modify or remove any policies that include the offending Email Address Domain.

Step 2 – Remove the Domain from the list of Accepted Domains

This step is pretty self-explanatory. In this situation we just remove the domain from the list of accepted domains on the Exchange server. This will tell the Exchange server not to accept emails destined for that domain. This can be done from the same location in EMC for Exchange 2007/2010, and from the Mail Flow system in Exchange 2013 by clicking on Accepted Domains, and then right clicking on the domain you want to remove. Selecting delete will remove that domain.

Step 3 – Remove Email Addresses

This part can be a little tricky. Removing the email address policies won’t necessarily remove the email addresses that users have from their accounts, and if those addresses remain you could still end up having mail go places you don’t want it to. Resolving this issue requires some work with PowerShell in the Exchange Management Shell (EMS).

After the Email Domain is removed, open EMS and run the following command:

get-mailbox | where {$_.emailaddresses -like “*domain.com”}

Replace domain.com with whatever domain you’ve removed. This will give you a list of all the users that have one or more email addresses attached to their domain that match the domain you’ve removed. If there are none, you’re done. If there are some mailboxes with the domain attached, you’ll want to run the following script to remove them:

$users = get-mailbox | where{$_.emailaddresses -like “*domain.com”}
foreach ($user in $users)
{
$addresses = (get-mailbox $user.alias).emailaddresses
$fixedaddresses = $addresses | where {$_.proxyaddressstring -notlike “*domain.com”}
set-mailbox $user.alias -emailaddresses $fixedaddresses
}

This will reset the email addresses on the account.