Zoho Banner September 2011

I upgraded a client’s CAS servers recently from Exchange 2007 Service Pack 2 Update Rollup 5 to Service Pack 3 Update Rollup 13 in preparation for upgrade to Exchange 2013.  Following the restart after the Update Rollup had completed I found I could not log into OWA.  Instead I got a blank page with a URL similar to the one shown below.


I found several suggestions for what might be the problem on the web, but the one that worked for me was to run the UpdateOwa.ps1 Powershell script in the Bin folder under the Exchange installation path.

It was required on both CAS servers, so at least it was consistent :-)

When you install a new version of Exchange or apply a Cumulative Update certain AD attributes are updated to reflect the change.  The updates are made in three different directory partitions (also known as naming contexts): Schema, Configuration and Domain.  The following Microsoft TechNet article is a good reference for the different versions and the corresponding attribute values.


You can check the values manually….or you could do it the easy way with Powershell.  Here’s a Powershell sample to give you values across the three partitions (assumes a single domain forest):


# Exchange Schema Version
$sc = (Get-ADRootDSE).SchemaNamingContext
$ob = "CN=ms-Exch-Schema-Version-Pt," + $sc
(Get-ADObject $ob -pr rangeUpper).rangeUpper

# Exchange Object Version (forest)
$cc = (Get-ADRootDSE).ConfigurationNamingContext
$fl = "(objectClass=msExchOrganizationContainer)"
(Get-ADObject -LDAPFilter $fl -SearchBase $cc -pr objectVersion).objectVersion

# Exchange Object Version (domain) - assumes single domain forest
$dc = (Get-ADRootDSE).DefaultNamingContext
$ob = "CN=Microsoft Exchange System Objects," + $dc
(Get-ADObject $ob -pr objectVersion).objectVersion

The output will looking something similar to screenshot shown below (showing the values for Exchange Server 2013 CU5):


I had an interesting one recently when submitting a certificate request to a Windows Certificate Authority using certreq.exe.  The error that came back was:

The disposition message is “Error Parsing Request The request subject name is invalid or too long. 0×80094001 (-2146877439)”

I found several links to possible solutions but, as it turns out, the problem in my case was the subject name (specified an X.500 DistinguishedName) was too long.  It seems that the CA limits the subject name field to 64 characters.  Mine was around 80 characters, which is not unusual for a DN.

The workaround is to remove the 64 character limit by running the following command:

certutil -setreg ca\EnforceX500NameLengths 0

The CA service needs to be restarted after running the command.

The Microsoft TechNet article that provides more detail can be found here.

I’ve had my Lenovo Ideapad Yoga 13 for a little over a year now. Generally, I’m very happy with it.  It has two internal SSDs, 8GB RAM and an Intel Core i7 processor.  Windows 8.1 runs very nicely on it.  I use the Ideapad for my day-to-day work as well as running test labs in Hyper-V.  Memory is generally my main limitation with Hyper-V, but mostly I can starve the VMs of RAM as performance isn’t a key issue for me for demos and/or testing purposes.  [As an aside, Exchange 2013 is a complete resource hog and won't run nicely unless you give each machine at least 4GB of RAM, which makes running a DAG near impossible for me].   Recently, I noticed that my disk latency (average response time) on the SSD that I run the VMs off was really high (around 11,000ms).  Ok, I was running 3 VMs simultaneously, but still!  So I downloaded AS SSD Benchmark to see how my SSD was performing.  The overall result was 438, which is not great when compared with what others have posted on line with the same SSD.

as-ssd-bench M4-CT256M4SSD3 15.07.2014 8-31-44 a.m.

After some deep thinking (i.e. staring idly into space over a coffee), the idea struck me that Bitlocker might be the culprit.  So I disabled Bitlocker for that drive and tried again. The difference was significant (around 20%) without being remarkable.  Interestingly, the read times before and after were almost identical.  The write times were where the difference was appreciable.

as-ssd-bench M4-CT256M4SSD3 15.07.2014 4-29-01 p.m.

The disk is still performing slowly compared with others online.  I checked my other SSD (a Samsung) and it was also slow, so the conclusion I’ve reached is that there must be some other factor (controller?) causing the slowness.  It would be interesting to hear what others with Ideapads are seeing, or if you have any ideas on how to improve performance.  Windows 8.1 is apparently optimised for SSD use, so I haven’t found any silver bullet for speeding things up.

Despite Active Directory having been around for more than 10 years, I still find new implementations proceeding without directory service access auditing enabled.  For me, auditing of who does what, where and when in your directory is crucial information.  I can’t fully fathom why Microsoft doesn’t have it enabled with some sensible defaults out of the box, but maybe that’s just me.  If you download and install Microsoft’s Security Compliance Manager 3.0, the Domain Controller baseline contains good auditing defaults.  Anyway, here is a quick “how to” guide for enabling basic directory service access auditing in Windows Server 2012 R2 Active Directory.

Getting auditing going is done in two key steps.

  1. Configuring Group Policy with the appropriate auditing settings
  2. Configuring the System Access Control List (SACL) at the appropriate level(s) in the directory

Ok, let’s get started with the first item (Group Policy).  For this, you will need a GPO linked to the Domain Controllers OU.  You can either use the Default Domain Controllers Policy or create a new one specifically for auditing.  My preference is to leave the DDCP at its defaults and create a new GPO with the settings.

Before the days of granular auditing settings you would configure your directory service access auditing under:

Computer Configuration->Policies->Windows Settings->Security Settings->Local Policies->Audit Policy


These settings belong to the dark days of pre-Windows Server 2008 when only the 9 auditing categories were available.  You don’t want to use this setting.  Instead you want to use the more granular auditing sub-categories introduced first in Windows Server 2008.

The first thing you need to do is enforce the use of the sub-categories in case someone unwittingly turns on the legacy auditing mentioned above.  To do this, enable the following setting:

Computer Configuration->Policies->Windows Settings->Security Settings->Local Policies->Security Options->Audit: Force audit policy subcategory settings….[it goes on a bit, but you get the picture]


Now we need to enable auditing for the specific sub-categories we are interested in.  To do this go to:

Computer Configuration->Policies->Windows Settings->Security Settings->Advanced Audit Policy Configuration->Audit Policies->DS Access

… and enable Audit Directory Service Access.  I would also enable Audit Directory Service Changes as that can provide you with complementary audit events, including before and after information for changed attribute values (really very useful).  Success and Failure?  Perhaps, but unless you have firm requirements to capture failure events then  just choosing Success can save the reduce the number of events generated.


Right, remember to link your new GPO to the Domain Controllers OU and that’s it for the GPO side of things.  You might be thinking that’s all you need to do, but unless you’ve done part 2 you won’t see the required events generated.

Now you might be interested in just certain parts of your directory, but if you don’t have an obvious place to begin, consider turning on audit records from the top of your domain partition.   To do this, open the Active Directory Administrative Centre (dsac).  Yes, yes, you could use dsa.msc or adsiedit.msc too.

Right-click the top of the domain tree (“contoso” in my case) and bring up the properties.  Under Extensions you will see the Security tab.  From there select Advanced and then choose the Auditing tab.  If you want to be comprehensive, I would select the Everyone security principal, set Type to Success and Applies to: This object and all descendant objects.  For the permissions, again if you want to be comprehensive, set the following:

  • Write all properties
  • Delete
  • Delete subtree
  • Modify permissions
  • Modify owner
  • All validated writes
  • All extended writes
  • Create all child objects
  • Delete all child objects


Once you have applied the changes you’re pretty much ready to go.  You should now start to see comprehensive directory access events as well as the before and after values for changed objects.



One thing you might not be aware of is that there was a bug in the RTM version of Windows Server 2012 R2 which meant that the directory service change information events did not get captured.  Of course, by now you will have your R2 servers fully patched, but just in case you are still running RTM be aware that you will need the download from KB2887595 for the change information to be available.

Bear in mind that, if you have a lot of auditing going on in your security logs on your DCs, the events are going to be overwritten pretty regularly even if you beef up the size of your security event log.  As part of defining your audit strategy you should work out your requirements for storing key events.  There are a number of ways to do that, including leveraging some kind of centralised audit collection system (or SIEM), but that’s beyond the scope of this article.

I helped a customer out with a problem recently.  They had been running Windows Server Backup on an Exchange 2013 CU3 server.  The backups had been configured to “VSS Full” and the scheduled jobs were showing as completing successfully.  The only issue was that the mailbox database transaction logs were not be deleted/removed by the backup job.  I had a close look at the configured backup options and they looked to be fine.   

The only obvious sign that something was wrong (other than the fact that the logs were not being cleared) was that the backup status (Get-MailboxDatabase -Status | fl name, *backup) was not showing a date/time stamp next to LastFullBackup.  Instead the date/time stamp indicated that a copy backup had taken place (LastCopyBackup).

After a fair bit of research I found the following had worked for some other people in the same position:

  1. Open REGEDIT and browse to:


  1. Add a new DWORD value named EnableVSSWriter, and set its value to 0.
  2. Exit Registry Editor and then restart the Microsoft Exchange Replication service.

This worked for my customer too!  It doesn’t appear to be well documented, so I thought I would share it here.

I fell foul of this one the other day and it took a while to figure out what to do about it. Here’s the scenario:

You deploy a new Group Policy Preferences (GPP) setting to create a folder on a workstation and specify the “Apply once and do not reapply” option. Unsurprisingly, this implies the GPP item will apply only once and will not run again!


But what if you have a problem on a specific target computer where the computer thinks it has already applied the GPP setting once? You won’t get the setting to reapply using the traditional gpupdate /force option. Instead you must look in the registry of the affected computer and look for the RunOnce entries. These are located here:

HKEY_CURRENT_USER\Software\Microsoft\Group Policy\Client\RunOnce
HKEY_LOCAL_MACHINE\Software\Microsoft\Group Policy\Client\RunOnce

The registry string values (REG_SZ) shown correspond to the RunOnce settings. Instead of descriptive text these entries have (spectacularly unhelpful) GUID-style names.


Ok, so armed with this information, how do you go about identifying the GUID-style name with your GPP setting? Don’t be led down the path of thinking the GUID-style name will match the GUID of your GPO – it doesn’t. That kind of make sense as a single GPO can have multiple GPP settings. The answer lies buried within the XML of the GPP setting. To get to the XML, right-click the GPP item within the GPO Editor and select All Tasks -> Display XML. Once you can see the XML look for the line starting with “FilterRunOnce” line. The value shown next to the “ID” is the one that corresponds to the registry entry.





To get the GPP setting to re-apply to the problem workstation, simply delete the relevant string value from the registry and force the policy to re-apply (gpupdate /force).

I had a requirement recently to try and find out where and when a whole lot of mailboxes were hidden from the GAL.  Yes, fingering some poor sucker for the blame is an immensely satisfying task, isn’t it?  I’ve found that an effective way to do this is to query the AD replication metadata for the attribute concerned (in this case ‘msexchhidefromaddresslists’).  The replication metadata will provide you with the date/time for when the attribute value was last changed as well as the name of the DC where the last change was made.  From there you can search the Security Event Log on the DC in question for the audit events corresponding to the change.  This of course assumes that you have Audit Directory Service Changes switched on.

Typically, I would use the excellent Repadmin.exe command line tool to query the replication metadata, e.g. -

Repadmin /showobjmeta MyDC1 “CN=MyUser,OU=User Accounts,DC=contoso,DC=com”

However, in this case someone had already reversed most of the changes (i.e. unhidden the mailboxes) and I needed to query a large number of objects to find some others that were still hidden, hoping that some of them would have a common data/time stamp.  For this the Repadmin.exe would work but would be hopelessly inefficient.  And what (I said to myself) is the best method for performing bulk operations such as this?  Yes, that’s right:  Powershell to the rescue!

After some Googling, I found an excellent code snippet from Powershell MVP Brandon shell that hooks into the underlying .Net class to expose the replication metadata.  His is the clever bit (that’s why he’s paid the big bucks) – I’ve basically just done the wrapper to perform a bulk query and output the results to a CSV file.  Here’s the script for your enjoyment.


# Name: BulkReportReplicationMetadata.ps1
# Author: Tony Murray
# Version: 2.0
# Date: 27/03/2014
# Comment: PowerShell 2.0 script to find change times
# for an individual AD attribute using replication metadata
# Some bits borrowed from: Get-ADObjectREplicationMetadata.ps1
# Brandon Shell (www.bsonposh.com)

# import the AD module
ipmo ActiveDirectory

# Define variables
$domain = (get-addomain).dnsroot # Use the current AD domain
$property = "msexchhidefromaddresslists" # This is the AD attribute we are interested in
$outfile = "c:\csv\outfile.csv" # CSV output file

# Blow away the existing file if it exists
if (test-path $outfile) {remove-item $outfile}

# We will build our own CSV rather than work with export-csv
$header = "samaccountname,modified,dc"
Add-Content -Value $header -Path $outfile

$sb = "OU=Standard User Accounts,DC=contoso,DC=com" # Search base for where our mailbox users live
$fl = "(&(homemdb=*)(msexchhidefromaddresslists=TRUE))" # LDAP filter to find our users
$users = Get-ADUser -LDAPFilter $fl -searchbase $sb

# Loop through our list of users
foreach ($user in $users) {

    $objectDN = $user.distinguishedname # used for finding the replication metadata
    $name = $user.samaccountname # Just for info
    # Sets Context to Domain for System.DirectoryServices.ActiveDirectory.DomainController
    $context = new-object System.DirectoryServices.ActiveDirectory.DirectoryContext("Domain",$domain)
    # .NET Class that returns a Domain Controller for Specified Context
    $dc = [System.DirectoryServices.ActiveDirectory.DomainController]::findOne($context)
    # GetReplicationMetadata returns metadata from the DC for the DN specified.
    $meta = $dc.GetReplicationMetadata($objectDN)
    # Get the last time the attribute value was changed
    $ctime = $meta | %{$_.$Property.LastOriginatingChangeTime}
    # Get the DC that the change was made on
    $dcon = $meta | %{$_.$Property.OriginatingServer}
    # Build the values to write to the output file
    $line =  "`"$name`",`"$ctime`",`"$dcon`""
    # Write the line to the output file
    Add-Content -Value $line -Path $outfile

} # end foreach

The shrewd amongst you would ask why I didn’t query the Exchange (2010 in this case) audit log for this information. The answer is that I did, but couldn’t find the relevant audit entries. The Exchange audit events are only captured if the Exchange tools (EMC/EMS/ECP) were used to perform the change. In my case the changes had been made in bulk, probably using the AD cmdlets.

Reading the post title you maybe wondering whether I’ve taken leave of my senses.  Why call Robocopy from Powershell to count files when Powershell has a perfectly good method of doing this natively? For example,

(Get-ChildItem e:\powershell -Recurse -force | ?{! $_.PSIsContainer} | Measure-Object).count

Well, the problem comes in when an individual file length exceeds 260 characters.  At this point Powershell throws an error similar to the one below.

Get-ChildItem : The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.

At E:\Powershell\CountFiles.ps1:243 char:32

+ $hcountpost = (Get-ChildItem e:\powershell -Recurse -force | Measure-Obj …

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

+ CategoryInfo : ReadError: (\\myserver\homed… – blah blah:String) [Get-ChildItem], PathTooLongException

+ FullyQualifiedErrorId : DirIOError,Microsoft.PowerShell.Commands.GetChildItemCommand

The problem is not so much to do with Powershell as the underlying .NET APIs, as the following article succinctly explains.


This is where Robocopy comes in handy as it doesn’t suffer from the same limitations.  On the other hand Robocopy has its own output formatting that doesn’t play nicely with Powershell.  I came across a very handy code snippet from MVP Boe Prox that can help with this.  The only change I have made is to roll it up into a function (shown below for your pleasure).

Function Count-Files ($path) {
    $params = New-Object System.Collections.Arraylist
    $countPattern = "^\s{3}Files\s:\s+(?\d+).*"
    $sizePattern = "^\s{3}Bytes\s:\s+(?\d+(?:\.?\d+)).*"
    $return = robocopy $path NULL $params
    If ($return[-5] -match $countPattern) {
        $Count = $matches.Count
    } # end if
    else {
    $Count = 0
    } # end else
    Return $count
} # end Count-Files function




Another short blog posting (brevity is obviously my thing for 2014).

I occasionally come across environments in which Strict Replication Consistency is not enabled.  This is invariably because these environment have forests that were created with Windows 2000 server, but which have subsequently been upgraded.  If you need to know more about Strict Replication Consitency and why it is important for your AD environment, I don’t plan to bore you with the details here as this topic is well covered elsewhere.  The best article I have found on the topic is this one.


The article makes the essential point that if the environment does not have SRC enabled then you need to do two things:

  1. Ensure the required registry key is configured on each DC.  The quickest method to achieve this is using Repadmin as follows: repadmin /regkey * +strict
  2. Ensure any new DCs promoted within the forest automatically have SRC enabled by creating an operational GUID (actually a Container object in the Configuration Partition).  There are several ways to create the object, but as you know, I’m a fan of Powershell, so here’s the code to do it:


# Strict Consistency - add operational GUID
$cnc = (get-adrootdse).configurationnamingcontext
$path = "CN=Operations,CN=ForestUpdates," + $cnc
$obj = "94fdebc6-8eeb-4640-80de-ec52b9ca17fa"
New-ADObject -Name $obj -Type container -Path $path -OtherAttributes @{showInAdvancedViewOnly="TRUE"}