You know the 14 hive like the back of your hand, and can lookup a correlation id in 10 seconds flat. You know how to handle everything Health Analyzer can throw at you. Central Admin bores you – you like the cozy black and white of the PowerShell console. And now, some third party thing is broken, not logging, and all tech support can do is ask you to reboot the servers (which you did 3 days before you called support- FizzBin)
You have come a long way – it’s time to complete your training and become a SharePoint Debugging Blackbelt. You will be armed with three tools:
- dotPeek – a free .NET decompiler from JetBrains. Yes, we’re going there.
- PowerShell – this is just .NET in the command line. You’re about to kick some SharePoint butt.
- A working knowledge of SharePoint and .NET.
Rule #1: Know your Enemy
dotPeek allows you to decompile and look at the code of any managed .NET assembly. Including those in the GAC, and those written by Microsoft. SharePoint is, in the end, really just a huge ASP.NET app. Almost all SharePoint 3rd party add-ins are written in .NET. You see where I’m going here.
Isolate the problem. Do your best to get repeatable steps and know more or less what part of SharePoint or 3rd party is not working as expected. If the problem is on a particular page under _layouts, note the page, and then open it from the corresponding folder in the 14 hive. At the top, especially if it is a 3rd party, note the namespaces and assemblies involved. For example, the Page directive may have a “Inherits” attribute. Register directives may have a “Namespace” or “Assembly” attribute. Examine the page and see if you can identify a problem control.
For example, the case that led me to post this had a very specific page that was not behaving as expected. I looked at the page in the hive, and found a suspect control on the page, named SLActivityToolbox and a Nintex.Workflows.ServerControls assembly.
Install dotPeek on the server. It should be safe for production boxes, but if you can, do this in a test environment. You don’t have a test environment? You are not ready for this post then!
Examine the assemblies in dotPeek. Generally, they will be in the GAC. However, some 3rd party tools may be in the \bin folder of a web app, or even in the 14 hive. In my case, I opened Nintex.Workflows.ServerControls and started reading code. There, nestled in the ‘Render’ method, I found a suspect. It’s a given you’ll need to know some .NET code to do this, but the times I’ve done this, it’s usually fairly easy to read and figure out at least some problem areas.
Rule #2: Use your Enemy’s Weapons Against Them
In some cases, just perusing the code in dotPeek is enough to get to a solution. In other cases, it takes fighting back. Enter PowerShell, which as I’ve said is just command-line .NET. This means that you can load .NET assemblies and tinker. You see where I’m going.
I imported Nintex.Workflows.ServerControls with code like this:
$x = [Assembly]::LoadWithPartialName("Nintex.Workflow.Assemblies")
This post has a good overview of loading assemblies from various sources. Loading an assembly in this way is similar to adding a reference in a .NET project. All of the code within the assembly is now available in the commandline. Use it wisely, grasshopper.
From reading code, I suspected a method call SnippetRepository.GetAll() was the culprit. However, it needed a SPSite instance for me to call it. And here is where it really clicks that PowerShell is really just .NET. That SPSite instance can come from the built in SharePoint PowerShell commands:
$s = get-spsite http://somesite $r = new-object Nintext.Workflow.ServerControls.SnippetRepository $s $r.GetAll()
We get a SPSite instance and pass it to the constructor, then call GetAll. This call threw an exception, but confirmed my suspicions. Armed with this, I was able to chase down a modified library on the site and fix it, correcting the problem.
Rule #3 Use for Good, Not Evil
Another appropriate title for this post could be “How to debug SharePoint like a crazy man.” Use these techniques at your own risk. You can seriously hose a farm doing this, so only attempt in situations where you have nothing to loose or really know what you’re doing. In my case, unfortunately, it was the first.
Since the code I ran only queried and did not update, I felt somewhat safe. Plus, this was in a test environment, but even so, this probably wasn’t the safest debugging session I’ve ever done. That said, you do what you have to, and in extreme cases, it’s good to know you have some heavy weapons like dotPeek and PowerShell to bring in on particularly hairy situations.