Unexpected error has occurred accessing /_layouts/termstoremanager.aspx

Came across an interesting issue in a test environment where our test user and I couldn’t access the Term Store Manager, and were getting the “unexpected error has occurred” message.

A quick look at the ULS logs showed the message:

System.InvalidOperationException: The Taxonomy feature (Feature ID "73EF14B1-13A9-416b-A9B5-ECECA2B0604C") has not been activated.

To find out the missing feature, I used PowerShell to interrogate it:

Get-SPFeature -Identity 73EF14B1-13A9-416b-A9B5-ECECA2B0604C

DisplayName                    Id                                       Scope
-----------                    --                                       -----
TaxonomyFieldAdded             73ef14b1-13a9-416b-a9b5-ececa2b0604c     Site

I couldn’t find the TaxonomyFieldAdded feature in the list of Site Collection Features in the browser (nor do I ever recall seeing it in the past). I went back to my friend PowerShell and tried:

Enable-SPFeature -Identity "TaxonomyFieldAdded" -Url http://testsite

A refresh of …/layouts/termstoremanager.aspx and the page loaded as expected.

Turn Off Second Stage Recycle Bin

A quick way to turn off the Second Stage Recycle Bin in SharePoint 2010 – set the quota to zero. In Central Admin, you cannot set a zero value, but there is an option to turn it off.

foreach ($webApp in Get-SPWebAPplication)
{
    $webApp.Name
    $webApp.SecondStageRecycleBinQuota = 0
    $webApp.Update()
}

Simple enough, and while working on a client site I’ve come across an issue with a particular web application and received the error:

Exception setting "SecondStageRecycleBinQuota": "Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))"
At line:4 char:13
+     $webApp. <<<< SecondStageRecycleBinQuota = 0
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : PropertyAssignmentException

Both in PowerShell and in Central Admin, I was able to set the quota for the second stage recycle bin to as low as 1%, but not turn it off.  In Central Admin, I was getting this error:

CA-SecondStageRecycleBin

After turning on verbose logging, this error was picked up:

Access Denied for /_admin/vsgeneralsettings.aspx?type=gen&WebApplicationId=707dac5e9db64a96b509c5f153ace591&IsDlg=1. StackTrace:  
 at Microsoft.SharePoint.Utilities.SPUtility.HandleAccessDenied(HttpContext context)   
 at Microsoft.SharePoint.Utilities.SPUtility.HandleAccessDenied(Exception ex)   
 at Microsoft.SharePoint.Library.SPRequest.GetAdminRecycleBinItems(String bstrSiteUrl, Object& pvarItems, UInt32& pdwNumberOfItems)   
 at Microsoft.SharePoint.SPRecycleBinItemCollection.EnsureContent()   
 at Microsoft.SharePoint.SPRecycleBinItemCollection.get_Count()   
 at Microsoft.SharePoint.SPRecycleBinItemCollection.GetSortedSecondStageIds()   
 at Microsoft.SharePoint.SPRecycleBinItemCollection.DeleteAllSecondStageItems()    
 ... 

It appeared that the logged in account did not have access to the recycle bin to remove the contents.  This was not a problem for other Web Applications, and did not use the Farm Service Account as I expected.  Granting the logged in account with Full Control to the Web Application User Policy for the problematic Web Application allowed me to turn off the second stage recycle bin with both PowerShell and Central Admin.  I can only presume the logged in account already had access to the other Web Applications which is why they worked.

Backup SVN with PowerShell

I work with a team of developers and utilise SVN for our source control. The backup script in place was a simple batch file and had a few shortfalls, so I re-wrote it with PowerShell.

Essentially it checks the location of the repositories, performs a svnadmin dump to another location on the same server, then copies them over to a network share that will get put onto tape.

$RepoLocation = "C:\Repositories"
$RepoBackupLocation = "C:\ReposBackup"
$FileServerDestination = "\\file\Backups\SVN"
 
foreach ($repo in (Get-ChildItem($Repolocation)))
{
    if (!$repo.Directory)
    {
        #$repo.Name
        $svnDumpSource = $RepoLocation + "\" + $repo.Name
        $svnDumpDest = $RepoBackupLocation + "\" + $repo.Name + ".dmp"
        svnadmin dump -q $svnDumpSource &gt; $svnDumpDest
     }
 
}
 
robocopy ($RepoBackupLocation+"\") $FileServerDestination *.dmp /Z /NP

Updating SharePoint User Properties in PowerShell

I recently experienced an issue whereby I lost a whole heap of data from the user profile service.  The UPS was the data source (custom property), and not available in active directory nor anywhere else.  The circumstances leading to the data loss is a separate story, but needless to say it was relatively straight forward to recover the data and re-enter it against the user profiles.

Data Recovery

Luckily I had a relatively recent copy of the Profile database, and the first thing to do was restore this against my test environment.  After a quick inspection there were three key tables:

  1. UserProfile – stores information about the user
  2. PropertyList – list of all the properties, including custom ones
  3. UserProfileValue – where the actual data is stored

In this case, the custom property was called DeskNumber.  I’ve formatted the SELECT statement for use in importing the data:

USE [Restore_ProfileDB]
 
--NB there is a deliberate typo in the next line, replace "@" with "a"...sorry, seems to be a wordpress bug...
SELECT '"' + up.NTName + '" = "' + c@st(upv.PropertyVal AS v@rchar(20))+ '";'
FROM UserProfile up
INNER JOIN UserProfileValue upv ON upv.recordid = up.RecordID
INNER JOIN PropertyList pl ON pl.PropertyID = upv.PropertyID
WHERE pl.PropertyName LIKE '%DeskNumber%' AND upv.PropertyVal IS NOT NULL

Did I mention that you would only do this exercise on a test environment? 🙂

Here are some sample results:

image

Data Import

As we should not use SQL to populate the data, PowerShell comes to our rescue.  The results from SQL constructs the data in key-value pairs for use in a hash table.  Simple copy and paste the results from SQL into the script to populate $userData.

Then run the script, taking care of using the correct:

  1. MySite location
  2. User profile property
  3. Set of users
Add-PSSnapin Microsoft.SharePoint.Powershell
 
$userData = @{
"domain\aas" = "18.61";
"domain\gle" = "M.24";
#...(repeat for each user)
"domain\sch" = "M.25";
}
 
$mySiteHostSite = Get-SPSite "http://mysites"
$mySiteHostWeb = $mySiteHostSite.OpenWeb()
$context = Get-SPServiceContext $mySiteHostSite
$profileManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)
 
foreach ($d in $userData.Keys) {
    $up = $profileManager.GetUserProfile($d)
    $up["DeskNumber"].value = $userData[$d]
    $up.Commit()
    }

This worked great for the custom properties for which we needed to recover.  It’s pretty dumb, it doesn’t cater for disabled/deleted accounts so may throw the odd error or two on those.  I could have gone for a completely integrated script that did the SQL query too, but this was a once-off exercise and it was quicker to just copy and paste the data over. 

Special thanks to Phil Childs @ Get-SPScripts.com, and his script for uploading profile pictures to SharePoint using PowerShell which I loosely used as my guide for putting the latter half together.

Fixing missing server side dependencies: [MissingFeature]

Have you ever seen this while looking through the SharePoint Health Analyzer on your farm?

[MissingFeature] Database [Z_PRODRESTORE] has reference(s) to a missing feature: Id = [20e9ecab-2d22-41eb-892d-933afc32793e]. The feature with Id 20e9ecab-2d22-41eb-892d-933afc32793e is referenced in the database [Z_PRODRESTORE], but is not installed on the current farm. The missing feature may cause upgrade to fail. Please install any solution which contains the feature and restart upgrade if necessary.

It is certainly a bit cryptic.  SharePoint has a reference to a feature that doesn’t exist anymore, and its not too keen to give you any clues about it. But if you were to click here, you’d certainly find a melange of professional who’d be willing to tell you how you can get that feature.

This tends to happen when a feature has been removed from the farm, but not deactivated from the sites that may have been using it.  I encountered this recently with five of these such errors, and here is my approach:

Try and work out what the feature is

This doesn’t work in every case, but you can give it a shot, run this PowerShell command:

(Get-SPSite http://site ).Features

You may get some information out of the Properties property.  This helped me identify two InfoPath forms that I had removed from Central Admin, but hadn’t deactivated on a site collection.  Simply re-adding the forms, then deactivating the forms in the offending site collection made two of these errors go away.

The problem with this approach is that there may not be information available in the Properties property, and you may need to check every site collection to find the missing feature.

Solution 1 – the easy way

Thankfully there is a nice, elegant solution put together by Phil Childs:  Removing features from a content database in SharePoint 2010 using PowerShell.

Phil’s script will check all of the sites in a content database and programmatically remove the feature references – I’ve run this and it works as advertised.  If you can, run this on a non-production environment first!

Solution 2 – the hard way

I also found another way of achieving the same result and inspired by a comment left on a forum somewhere (and I cannot find the link!).  Essentially their suggestion was to create a feature with the same feature ID as per the error, install it onto the farm, deactivate the feature, and remove the dummy feature from the farm.

I tested this approach and I must say this did work!  Chapter 13 of Professional SharePoint 2010 Administration gave an excellent example on how to create a dummy feature and solution package.  Same note as above about running this on a test system before trying it on production.

Overall

If you can’t work out the missing feature and fix it easily, then go with Phil’s method per Solution 1.  If anyone is crazy enough to want to know more information about how to achieve Solution 2 and more info on the purest forskolin , drop me a comment below.