We’ve recently started making some decisions as to the layout of our primary intranet site (the information architecture of the site that is). One of the things we decided was that we wanted all divisions to be in separate site collections but for each of them to share a single database. We also wanted to create a central document center site and knowledge base site which would, along with all remaining root content, be in it’s own database. Our current structure just has everything in one large site collection. In order to accomplish this I needed to take the primary content database offline while I moved/converted divisional web sites into site collections.

I was able to use the existing addcontentdb command to create the new content database but I needed to create a new command, called gl-managecontentdbsettings, to take the existing one offline (I already have a command to convert a sub-web to a site collection). I decided that rather than just limit the command to changing the status I’d go ahead and make it so that it could adjust any of the properties that you could otherwise adjust via the browser by going to the Manage Content Database Settings page (Central Administration > Application Management > Content Databases > Manage Content Database Settings). This included the status, the maximum number of allowed sites, the number of sites allowed before a warning is sent, and the search server (there’s already a built in command to remove a content database so I didn’t worry about that).

The code to do all of this was extremely simple – the only thing that made me pause for a bit was the setting of the search server (I had to dig into Microsoft’s code to see how that was accomplished but in the end it turned out to be pretty simple):

 1public override int Run(string command, StringDictionary keyValues, out string output)
 2{
 3    output = string.Empty;
 4 
 5    InitParameters(keyValues);
 6 
 7    string dbname = Params["dbname"].Value;
 8 
 9    using (SPSite site = new SPSite(Params["webapp"].Value))
10    {
11        SPContentDatabase db = null;
12        foreach (SPContentDatabase tempDB in site.WebApplication.ContentDatabases)
13        {
14            if (tempDB.Name.ToLower() == dbname.ToLower())
15            {
16                db = tempDB;
17                break;
18            }
19        }
20        if (db == null)
21            throw new Exception("Content database not found.");
22 
23        bool modified = false;
24        if (Params["status"].UserTypedIn)
25        {
26            db.Status = (SPObjectStatus)Enum.Parse(typeof(SPObjectStatus), Params["status"].Value, true);
27            modified = true;
28        }
29 
30        if (Params["maxsites"].UserTypedIn)
31        {
32            db.MaximumSiteCount = int.Parse(Params["maxsites"].Value);
33            modified = true;
34        }
35        else if (Params["setmaxsitestocurrent"].UserTypedIn)
36        {
37            if (db.CurrentSiteCount < db.WarningSiteCount)
38                db.WarningSiteCount = db.CurrentSiteCount - 1;
39            db.MaximumSiteCount = db.CurrentSiteCount;
40            modified = true;
41        }
42 
43        if (Params["warningsitecount"].UserTypedIn)
44        {
45            db.WarningSiteCount = int.Parse(Params["warningsitecount"].Value);
46            modified = true;
47        }
48 
49        if (Params["searchserver"].UserTypedIn && !string.IsNullOrEmpty(Params["searchserver"].Value))
50        {
51            // If they specified a search server then we need to try and find a valid
52            // matching search server using the server address property.
53            SPSearchService service = SPFarm.Local.Services.GetValue("SPSearch");
54            SPServiceInstance searchServiceServer = null;
55            foreach (SPServiceInstance tempsvc in service.Instances)
56            {
57                if (!(tempsvc is SPSearchServiceInstance))
58                    continue;
59 
60                if (tempsvc.Status != SPObjectStatus.Online)
61                    continue;
62 
63                if (tempsvc.Server.Address.ToLowerInvariant() == Params["searchserver"].Value.ToLowerInvariant())
64                {
65                    // We found a match so bug out of the loop.
66                    searchServiceServer = tempsvc;
67                    break;
68                }
69            }
70            if (searchServiceServer != null)
71            {
72                db.SearchServiceInstance = searchServiceServer;
73                modified = true;
74            }
75            else
76                throw new Exception("Search server not found.");
77        }
78        else if (Params["searchserver"].UserTypedIn)
79        {
80            // The user specified the searchserver switch with no value which is what we use to indicate
81            // clearing the value.
82            db.SearchServiceInstance = null;
83            modified = true;
84        }
85 
86        if (modified)
87            db.Update();
88    }
89 
90    return 1;
91}

The command I created is detailed below.

Using this command is straightforward. The only odd part is the setting of the search server. If you want to set the value simply provide the server name along with the -searchserver switch. But if you want to clear the value just provide the -searchserver switch alone with no value (not "" but literally no value). I probably should have done this differently but it works. The other thing that’s odd is that if you look in the browser you’ll see that the drop down for status contains “Ready” and “Offline” – this actually corresponds to “Online” and “Disabled” (which is strange because the SPObjectStatus enum contains an “Offline” value but if you tried to use that to set it offline it doesn’t appear to have an affect (at least it doesn’t change the value in the browser – I didn’t actually test if it prevents new sites from being created). The syntax of the command can be seen below:

C:\>stsadm -help gl-managecontentdbsettings

stsadm -o gl-managecontentdbsettings

Sets the status and site limits for a content database.

Parameters:
        -dbname <content database name>
        -webapp <web application url>
        [-status <online | disabled>]
        [-maxsites <maximum number of sites allowed in the db / -setmaxsitestocurrent (sets the max value to the current value to keep the database online but prevent new sites from beeing added)>]
        [-warningsitecount <number of sites before a warning event is generated>]
        [-searchserver <search server (leave empty to clear the search server)>]

Here’s an example of how to set all the properties of a content database:

stsadm –o gl-managecontentdbsettings -webapp "http://intranet/" -dbname intranet1_site_pair -status disabled -maxsites 15000 -warningsitecount 9000 -searchserver spsearchsvr