Friday, January 29, 2010

Useful and Free SharePoint Tools (Part 3)

It has been a while since my previous "Useful and free SharePoint Tools" post. Over the past period I have ran into some more brilliant tools and didn't want to keep them from you, so here we go again! :-)

Just for reference:
Part 1: Useful and Free SharePoint Tools (Part 1)
Part 2: Useful and Free SharePoint Tools (Part 2)

SharePoint ULS Log Viewer
Do you know that feeling: You have to troubleshoot an issue and dive into the ULS log. Soon you find out how difficult it is to find what you are looking for in these logs. When using Notepad, you can try to search on time stamp or error message, but filtering is out of the question. Fortunately a guy at Microsoft created a great tool that offers searching and filtering capabilities. Just open a ULS log file and go crazy. Life suddenly becomes a lot easier :-)
Link: http://ulsviewer.codeplex.com/

Zevenseas SharePoint Search Coder
This tool is useful for developers and IT Pro's. Using this tool you can generate search queries, but also send them to SharePoint, using the object model or web services. I have used this tool often to troubleshoot some search issues I encountered. By entering the search query you can see exactly which data is returned and therefore determine if the search engine is the issue, or some code (web part for example) that processes the returned data.
Link: http://mosssearchcoder.codeplex.com/

SharePoint Feature Administration and Clean Up Tool
Ever seen the error "failed to determine definition for feature with id <GUID>" in your ULS log? This means that a feature is still registered as active somewhere in your environment, but is not installed anymore. Unfortunately there is no way using the GUI to fix this issue. The SharePoint Feature Administration and Clean Up tool has the answer for this issue. When you start this tool, it has a button "Find Faulty Feature" in the lower right part of the window. This functionality searches for feature registrations of features that do not exist anymore and if found, it can delete these references. The tool can do other stuff with features, which I didn't need to far but I thought the clean up functionality is brilliant!
Link: http://featureadmin.codeplex.com/

SPTraceView
SPTraceView is a tool that connects to the tracing service of SharePoint and shows you all logged messages in real time. You can set filtering so only certain messages are displayed. The tool has an icon in the system tray and pops up a balloon if a message comes in. By clicking the balloon, a window with all captured messages is displayed. Really useful when troubleshooting!
The tool only has one "issue": It cannot display any messages higher than configured in the SharePoint Central Admin. For example if you set messages for the General category to High, you won't see Medium or Verbose messages in SPTraceView (or the ULS log for that matter). This is inherent to the way the tracing log is built.
Link: http://sptraceview.codeplex.com/

SPSFarmReport
Ever wanted to know how your farm is configured in high level? This tool can create a very high level report of your farm configuration. I have been looking for such a tool for quite a long time now. Even though this tool creates a nice report, I would like to see a little more detail in a next version. But until then.....another useful and free tool :-)
Link: http://spsfarmreport.codeplex.com/

PowerShell
The last one of this post isn't a tool by itself, but I have to say PowerShell rules!! I am not a developer, so creating applications/webparts/etc is not for me, but which IT Pro isn't a bit lazy by nature :-) Why do something manual if you can script it? Using other scripting languages, you couldn't use .NET objects so were very limited when it comes to SharePoint. But with PowerShell you can use every .NET object you like, so also SharePoint .NET objects!! And with the addition of 650+ PowerShell commandlets in SharePoint 2010, PowerShell becomes more and more important for the IT Pro. So if you haven't done much with it yet, LEARN POWERSHELL!! You will love it and it will make your life a lot easier!
Link: http://technet.microsoft.com/en-us/scriptcenter/dd742419.aspx

Thursday, January 28, 2010

[MOSS/WSSv3] Change the application pool of a web application

[ISSUE]
How should I change the application pool of a web application

[BACKGROUND]
Recently I ran into a situation where Microsoft had performed a MOSS Risk Assessment Program (MOSSRAP). One of the recommendations of Microsoft was to limit the amount of application pools used on one environment. Depending on your hardware specs, this number will be around eight. However the administrators had created about 50 web applications and configured an application pool for each one of them.

In order to adopt the Microsoft recommendation, the administrator went into IIS and changed the application pools manually. When they tried to add a new server to the farm, this triggered a reset of the configuration on all servers, basically resetting the application pools to the configuration known by SharePoint (each of the web application in its own application pool. This brought down the entire environment for several hours.

[TECHNICAL DETAILS]
During installation/configuration of SharePoint, SharePoint stores all configuration on web applications and application pools. It does that so it is able to deploy everything to a server which is joined to the farm with the correct settings. When you make manual changes to IIS, the settings in IIS do not match the configuration known to SharePoint and you might end up in deep shit.

[SOLUTION]
Unfortunately it is not possible to change the web application/application pool configuration via Central Admin. The only way is by using the SharePoint object model. On the Internet I found an article which described how you could use a PowerShell script to accomplish this configuration change:
Change application pools via PowerShell

This script did have one downside: It changed the configuration in SharePoint, however it did not change the configuration in IIS. To solve this, I found a method added to the SPWebApplication class in one of the Cumulative Updates called ProvisionGlobally. By using this method, you provision that specific web application on all servers running the web front end role. You can download the revised PowerShell script here.

After running this script the old application pools are still present in SharePoint AND IIS. In order to delete them from IIS, you need to write a script to Unprovision them. However the SPApplicationPool class does not have an UnprovisionGlobally method, so you need to run this script on each of the WFE servers.

Wednesday, January 27, 2010

[MOSS/WSSv3] Audit Log and MergeContentDBS

[ISSUE]
Audit log not migrated when using MergeContentDBS and old entries remain in old database

[DESCRIPTION]
Recently I migrated a site collection from one database to another using the StsAdm command MergeContentDBS. After this migration I found out that audit entries, stored in the audit log table of the database, were still present in the old database. In total this was occupying about 20GB of space. In one of the previous updates of SharePoint, Microsoft introduced the stsadm command trimauditlog, but unfortunately this command cannot be used to trim entries in the old database if the site collection in not in there anymore.

[WORKAROUND]
It would be a possiblity to manually delete the entries in the audit log, however with SharePoint you will end up with an unsupported environment after manually changing databases.

The only workaround I would currently have is to move out all remaining site collections to other databases and then delete the old database.

Tuesday, January 26, 2010

[MOSS/WSSv3] How to determine which server is used in Load Balancing configuration

[ISSUE]
When you are using multiple SharePoint Web Front End servers and load balancing (Windows NLB or otherwise), it is very hard to troubleshoot issues. Users hit one of the WFE servers and you have to figure out which one. SharePoint does not offer a quick and easy solution to do this for you.

[SOLUTION]
In order to solve this issue I have implemented a very simple, but highly effective solution. I just create an HTML file in the Layouts folder (C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\LAYOUTS) called server.htm. This file looks nothing more than:

<HTML>
<HEAD>
<TITLE>---SERVER NAME--- </TITLE>
</HEAD>
<BODY bgcolor=yellow>
<H1>---SERVER NAME---</H1>
</BODY>
</HTML>

On each server I replace the text "---SERVER NAME---" with the actual server name and the bgcolor with a different color (for example "green" or "red"). If a user then experiences issues, you can just have the user add the text "/_layouts/server.htm" to the site URL to show him the server he/she is on.

Like I said, very easy and highly effective! :-)

Tuesday, January 05, 2010

[MOSS2007] Crawling schedule alternative

[ISSUE]
On a customer environment, we were having some issues with the default search scheduler. On this environment we currently have more than 4.8 million items in the index and migrations are still happening. This means that incremental crawls run for several hours and sometimes even more than 24 hours.

By default it is only possible to schedule it once a day maximum (so not once every two days) and according to a Microsoft engineer, it is not advised to run a crawl when a previous crawl is still running. Somehow that can result in a corrupt SSP. Configuring a schedule to run each 15 minutes is therefore not an option.

[SOLUTION]
To solve this issue, I have created a PowerShell script. This script checks if a crawl is running and if not, starts a new incremental crawl. I have scheduled this script to run every 15 minutes.
[System.Reflection.Assembly]::Load("Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c") | out-null
[System.Reflection.Assembly]::Load("Microsoft.Office.Server, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c") | out-null
[System.Reflection.Assembly]::Load("Microsoft.Office.Server.Search, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c") | out-null

$serverContext = [Microsoft.Office.Server.ServerContext]::Default
$context = [Microsoft.Office.Server.Search.Administration.SearchContext]::GetContext($serverContext)

$sspcontent = new-object Microsoft.Office.Server.Search.Administration.Content($context)
$sspContentSources = $sspcontent.ContentSources

foreach ($cs in $sspContentSources)
{
  if ($cs.Name -eq "Local Office SharePoint Server sites")
  {
    Write-Host "NAME: ", $cs.Name, " - ", $cs.CrawlStatus
    if ($cs.CrawlStatus -eq [Microsoft.Office.Server.Search.Administration.CrawlStatus]::Idle)
    {
      Write-Host "Starting Incremental crawl"
      $cs.StartIncrementalCrawl();
    }
    else
    {
        Write-Host "Crawl running"
    }
  }
}