I’m starting to work on getting our Site Directory configured and the first thing I noticed after performing my test upgrade was there were tons of links in the site directory to dead sites. This is because in SPS2003 there was no mechanism (that I’m aware of at least) to clear out dead items in the list. With MOSS there’s now a timer job that can be configured to clean up the site directory.

I decided that I wanted to set this up as part of my upgrade script (which of course meant another new command which I called gl-setsitedirectoryscanviewurls). Setting this up can be done pretty easily via the browser by using the central admin tool (Central Administration > Operations > Site Directory Links Scan). I took all of the code from what I disassembled using Reflector (see One of the things I needed my upgrade script to do was to set the master site directory. This can be done easily enough using the central admin tool (Central Administration > Operations > Site Directory Settings).

I took most of my code from what I disassembled using Reflector (Microsoft.SharePoint.Portal.SiteAdmin.LinksCheckerJobSettings). I decided that I’ve grown tired of trying to work around the fact that Microsoft has not made more methods and constructors public and so I decided to just use reflection to mimic what the LinksCheckerJobSettings class does thus avoiding a lot of headaches and shortening my development time considerably (of course there’s always the risk that MS changes these methods but I feel safe with these particular objects). Basically all I’m doing is instantiating a LinksCheckerJob object and setting the appropriate values.

 1SPTimerService timerService = SPFarm.Local.TimerService;
 2if (null == timerService)
 3{
 4    throw new LinksCheckerException("Links Checker Timer Service Not Found.");
 5}
 6 
 7LinksCheckerJob job = timerService.JobDefinitions.GetValue("SPS-SiteDirectoryLinksChecker");
 8if (null == job)
 9{
10    // As I've grown tired of trying to get around the limitations of working with only public accessors I've decided to call the 
11    // internal accessors so this code now works exactly as the LinksCheckerJobSettings.SaveViewUrls() method which is what is called
12    // when you adjust the settings via the browser.
13 
14    //job = new LinksCheckerJob(timerService);
15    ConstructorInfo nonPublicConstructorInfo = typeof(LinksCheckerJob).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, new Type[] { typeof(SPTimerService) }, null);
16    job = (LinksCheckerJob)nonPublicConstructorInfo.Invoke(new object[] { timerService });
17 
18 
19    //job.SetDefaults();
20    MethodInfo setDefaults =
21        typeof(LinksCheckerJob).GetMethod("SetDefaults", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod);
22    setDefaults.Invoke(job, new object[] {});
23}
24job.SiteDirectoryConfig = urls;
25job.IsMetaDataSyncEnabled = updateSiteProperties;
26job.Update();

The syntax of the command can be seen below.

C:\>stsadm -help gl-setsitedirectoryscanviewurls

stsadm -o gl-setsitedirectoryscanviewurls

Sets the site directory links scan job options.

Parameters:
        -urls <views to scan (separate multiple views with a comma)>
        -updatesiteproperties <true | false>

Here’s an example of how to set the site directory links scan properties:

stsadm –o gl-setsitedirectoryscanviewurls –urls "http://intranet/sitedirectory/siteslist/allitems.aspx" –updatesiteproperties true