Monday, August 28, 2017

AD Synchronization Error When Adding Exchange 2016

When I implement hybrid mode for an organization, we typically implement Exchange Server 2016 to be the long term hybrid server. This provides the most recent Exchange Server version for management.

Today when I was installing Exchange Server 2016 into an Exchange 2010 organization we started getting directory synchronization errors for some system mailboxes (four of them). This occurred after I ran /PrepareAD, but before the remainder of Exchange Server 2016 was installed.

SystemMailbox{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}@XXXXX.com

Unable to update this object in Azure Active Directory, because the attribute [Username], is not valid. Update the value in your local directory services.
We only noticed these errors because Office 365 sent an Identity Synchronization Error Report that listed them.

When I looked in Synchronization Service Manager to see the details in Azure AD Connect, the following errors were there in the export to the Office 365 tenant:
I did some searching around and found a few articles that talked about manually updating attributes for these objects. However, when I looked at these objects the data didn't match what those articles were talking about.

Eventually I found a posting in an MS discussion forum that said to just wait until the install was finished. Apparently /PrepareAD creates the objects, but their configuration is not complete until the rest of Exchange Server 2016 is installed.

Sure enough, after the Exchange Server 2016 install was finished the synchronization errors went away.

Posting in MS discussion forum for reference (see answer from Ytsejamer1):
I did also refresh the connector schema as suggested in this post. However, I did that after running /PrepareAD and before Exchange Server 2016 was installed. I can't say for sure whether this step is required.




 

Monday, August 21, 2017

Updating SIP Addresses in Skype for Business

When you migrate to Office 365, the preferred configuration is to have user email addresses and UPNs the same. Having a single identity makes it easier for users to understand.

If you are implementing Skype for Business in Office 365, it will take the UPN of the user as the Skype address. Again, keeping a single identity is good.

However, if you have an on-premises implementation of Skype for Business, then the Skype identity is configured in the attribute msRTCSIP-PrimaryUserAddress.  This attribute contains a SIP (session initiation protocol) address that looks like an email address but with “sip:” at the start. For example: “sip:user@contoso.com”.

The SIP addresses defined in your on-premises Skype for Business may or may not match the email addresses of the users. You need to verify whether the addresses match. If the SIP address does not match the email address, it is easy to change.

On the Skype Server run the following PowerShell command:
Set-CsUser -Identity userUPN -SipAddress "sip:emailaddress"

When you update the SIP address for UserA there are two considerations:
  • UserA will be signed out of Skype within about 1 minute. After UserA is signed out, they need to sign in again by using their new SIP address.
  • Any users with UserA as a contact are not updated immediately. These users need to sign-out and sign-in again for the contact to be updated and properly view presence information. However, this only works if the address book as been updated.
Address book updates are the big gotcha in SIP address updates. By default, Skype for Business clients use a cached address book that only updates once per day. Even if you force address book updates on the server, the new address information is not retrieved until the next day unless you manually delete the cached address book files from the client to force a reload.

To address this problem, you can switch clients to use an online address book. Clients using the online address book query the Skype for Business server each time they search the address book. When using the online address book, changes show up within a few minutes.

Address book look ups are controlled by client policies. By default, there is one policy named Global. You can update this policy to use online address book resolution with the following command:
Set-CsClientPolicy -Identity Global -AddressBookAvailability WebSearchOnly

Alternatively, you can create a new policy and assign that to users incrementally:
New-CsClientPolicy -Identity OnlyWebAB -AddressBookAvailability WebSearchOnly
Grant-CsClientPolicy -Identity UserName -PolicyName OnlyWebAB

The new client policy takes effect the next time the user signs in. To increase the likelihood that users have the new policy, you should configure it and then wait until the next day before making large scale changes.

Some useful links:

Sunday, August 13, 2017

Scripting Complexity vs. Simplicity

Note: Most of my blog posts are technical items that relate to performing a specific task or fixing a specific error. This one is more of an opinion piece. So, if my arguments sound reasonable, take the advice. If you disagree, by all means, go your own way.

I am a big believer that I need to understand the details of any script I run in a production environment. Unless that script is from Microsoft and provided to perform a specific task (such as migrating public folders), I will go through a script line by line to verify I understand it. This even applies to my own scripts. If I haven’t used a script for several months, I’ll review it before I use it again to make sure I know exactly what it’s doing.

I expect that most system administrators operate with the same requirement to understand the scripts they are running. At least I hope they do. I don’t want anyone blindly running a script I created without understanding the script and knowing what it will do in their environment.

So, from my perspective, running a script is very different from running a program/utility. A program is distributed as an executable and you simply need to trust the developer. I don’t need to trust a script writer if I can understand what the script is doing. The writer just saved me the effort of creating the script myself. It’s much faster to review and verify an existing script than it is to create one.

Simple is good, right?

If you need to understand a script, then simple is good. However, we often attempt want a script to be resilient to user error. That is, we want the script to do things like:
  • Not accept invalid values
  • Not make incorrect/invalid changes to objects
  • Warn when mistakes are about to be made
A more user-friendly script is good, but it becomes more complex and more difficult to interpret. So, does that mean complexity is good?

Know your audience

The balance of simple (but you need to know what your doing) and complex (with lots of error checking) depends on your audience. If the audience needs to understand the details of your script, then simplicity is better. If the audience does not care about the details inside the script then simplicity is less important. For example, if the help desk staff in your organization run standardized scripts to complete some specific tasks then user friendly is more important than simplicity. The help desk staff will be running the script without reviewing the contents or understanding how it works. So, if they give an invalid value, you need to account for that in your script. It’s worthwhile to make it user friendly to prevent errors in the production environment.

The customers I work with typically will look at my scripts before running them. So, these scripts need to be relatively short and understandable. The documentation that I provide for running these scripts also needs to be short and understandable. In this case simplicity is most important for the audience. For example, if there are several tasks that need to be accomplished such as updating email addresses, UPNs, etc. I will create separate scripts for each task. This makes each individual script easier to understand and document.

Striking a balance

I tend to work with customers that have varying knowledge levels and needs. Some of them would run a script without looking and others want a detailed understanding how the scripts work. I want my scripts to work in both scenarios. So, I need to put in some of the user-friendly bits like prompting for values when required and some basic checking for invalid values, but I don’t try to account for every possible error. To account for every possible error would be too much complexity.

Because I can’t (or won’t) put in tons of error checking, one thing I often do is display a confirmation on screen before performing an action. For example, I have a script to remove email addresses for a specified domain. Before script performs the action, it displays on screen the pattern being searched for and provides an email address from the first mailbox as an example of what is about to be removed. The script also displays the number of mailboxes that are being modified. Displaying this information allows the user to provide a final sanity check before approving removal from all mailboxes.

To make scripts more understandable, I use lots of comments that describe what each section of a script is doing.  This is useful for customers that want to review the script. It’s also useful for me when I want to review the script contents or modify the script. Embedding comment-based help in a script makes it easier to use, but detailed comments in the script are better for understanding how it works.

If you don’t get the right balance then your scripts won’t get used. That help desk person will think your script generates errors all the time and ignore it. The administrators you gave complex scripts to will build their own because they can’t understand yours.