A while back I had to debug the SQL Server 2008 setup code to find out why the Registry Consistency Check rule was taking an obnoxiously long time to complete on a particular server. While trying to apply SQL Server 2008 SP2, you will find that the Registry Consistency Check rule is executed. Now the setup UI didn’t show any progress for over an hour. When I checked a previous set of setup logs ,I found the following failure (from the Detail.txt file):
2011-04-17 15:06:53 Slp: d:14c36b1c9c26b2820a8\x64\FixSqlRegistryKey_x86.exe exit code: 1
2011-04-17 15:06:53 Slp: Rule ‘AclPermissionsFacet’ detection result: AreSqlAclPermissionsCanonical= False
2011-04-17 15:06:53 Slp: Evaluating rule : AclPermissionsFacet
2011-04-17 15:06:53 Slp: Rule running on machine: <machine name>
2011-04-17 15:06:53 Slp: Rule evaluation done : Failed
2011-04-17 15:06:53 Slp: Rule evaluation message: The SQL Server registry keys from a prior installation cannot be modified. To continue, see SQL Server Setup documentation about how to fix registry keys.
In another setup attempt (again from Detail.txt file), I found that the FixSqlRegistryKey_x86.exe did not log any message post the launch of the EXE:
2011-04-29 11:42:58 Slp: D:\Microsoft SQL 2008 SP2\x64\FixSqlRegistryKey_x64.exe exit code: 0
2011-04-29 11:42:58 Slp: Launching external tool: D:\Microsoft SQL 2008 SP2\x64\FixSqlRegistryKey_x86.exe
2011-04-29 11:42:58 Slp
If you capture a Process Monitor trace, you will find that the FixSqlRegistryKey_*.exe is traversing the registry keys pertaining to the SQL Server registry hive. The EXE (FixSqlRegistryKey_*.exe) looks up and fixes all non-canonical ACLs with the registry key and its child keys for the two hives below:
HKLM\Software\Microsoft\Microsoft SQL Server\
HKLM\Software\Microsoft\MSSQLServer\
Did I just read the word Canonical?!? Yes, you did. A canonical ACL must have ACEs sorted according to the following order:
1. Access-denied on the object
2. Access-denied on a child or property
3. Access-allowed on the object
4. Access-allowed on a child or property
5. All inherited ACEs
Reference: http://blogs.msdn.com/b/patcarna/archive/2009/02/09/the-access-control-list-is-not-canonical.aspx
If SQL Setup finds ACLs in non-canonical form, then it will try and fix the ACLs for the registry key and it’s sub-keys which have the ACLs in non-canonical form. If there are permission issues encountered while traversing the registry, then this might take a longer time to error out or fail with the error message mentioned above.
You have the following option to correct the non-canonical ACLs:
1. Locate non-canonical ACLs in two hives mentioned above and fix them manually.
2. Re-run the rules
3. Check which registry key the EXE takes a long time to move forward from or encounters an access denied error using a Process Monitor trace.
Note: Always use a backing file pointed to a local disk when capturing Process Monitor traces for prolonged periods. Refer this post for more details.
Once you have fixed the non-canonical ACLs, you should be able to successfully get beyond the registry consistency rule check without having to get lunch and dinner in between!
Since I didn’t want to sit and traverse through all the registry keys manually, I wrote a Powershell script to check if the ACLs for your SQL Server registry hive and it’s sub-keys are in canonical form or not and report back the key which is not in non-canonical form.
Function fnCheckCanonical { Param ([string] $regvalue) $reg = Get-ChildItem $regvalue -recurse Write-Host "Checking hive : " $regvalue foreach ($path in $reg) { $regkey = $path.ToString() $regkey = $regkey.Replace("HKEY_LOCAL_MACHINE","HKLM:") #Write-Host $regkey $acl = Get-Acl -Path $regkey if ($acl.AreAccessRulesCanonical.ToString().Equals("True")) { Write-Host "Verified key: " + $acl.Path.ToString() } else { Write-Host "Reg Key: " $acl.Path.ToString() Write-Host "IsCanoncial: " $acl.AreAccessRulesCanonical.ToString() Write-Host "Failed canonical check" } } } fnCheckCanonical HKLM:"Software\Microsoft\Microsoft SQL Server" fnCheckCanonical HKLM:"Software\Microsoft\MSSQLServer" fnCheckCanonical HKLM:"SOFTWARE\Wow6432Node\Microsoft\Microsoft SQL Server" fnCheckCanonical HKLM:"SOFTWARE\Wow6432Node\Microsoft\MSSQLServer"
ACLs don’t change into non-canonical forms just because they are having a bad day but it could happen when you use scripting tasks from .NET/VBScript/Powershell or subinacl.exe to incorrectly modify/add/remove ACLs on a registry key. Digging into the root cause of how they actually got into the state is as good as searching for a needle in all the haystacks in the world! Here is an article on how subinacl.exe could arrange ACLs incorrectly on Windows 2000: http://support.microsoft.com/kb/296865
Hope this helps you in fixing your non-canonical ACLs if you are unfortunate enough to run into this issue.
Pingback: Wednesday Weekly #sqlserver Links for 2011-28 | sqlmashup
Fantastic script! Thank you! I’m working though a similar issue with one of my users and I’m looking forward to running this script against her registry 🙂
Interestingly, when I run this on my own machine, I get 6 errors like this:
Get-ChildItem : Requested registry access is not allowed.
At C:\temp\checkCanonical.ps1:5 char:8
+ $reg = Get-ChildItem $regvalue -recurse
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (HKEY_LOCAL_MACH…SSQLServer\HADR:String) [Get-ChildItem], SecurityException
+ FullyQualifiedErrorId : System.Security.SecurityException,Microsoft.PowerShell.Commands.GetChildItemCommand
But when I run your script in a Powershell window ‘run as administrator,’ there aren’t any errors. I guess the take away is to always run this in a Powershell window with elevated privileges, but I am wondering which of these keys aren’t readable when not administrator.
Sadly, I have no idea how to build this error trapping into Powershell. Might be a cool idea for v.2! 😉
LikeLike
Good to know that this helped. I will see what I can do about the error handling in the future. You can handle errors using Try-Catch blocks in PowerShell: https://technet.microsoft.com/en-us/library/hh847793.aspx
LikeLike