So you’ve got a content database (perhaps you used the gl-createcontentdb
command) and now you want to create a site collection in that database. Problem is that you can’t do this easily via the browser and you definitely can’t do it via stsadm. There is a createsiteinnewdb
command and a createsite
command but the first will create a new database and the second will put the site collection in the “best match” database. But you need it in a specific database. What I decided to do was to create a new command: gl-createsiteindb
.
The code is pretty straight forward – the bulk of the code is just validation code:
1using System;
2using System.Collections.Specialized;
3using System.IO;
4using System.Text;
5using System.Web.Configuration;
6using Lapointe.SharePoint.STSADM.Commands.SPValidators;
7using Microsoft.SharePoint;
8using Microsoft.SharePoint.Administration;
9using Lapointe.SharePoint.STSADM.Commands.OperationHelpers;
10
11namespace Lapointe.SharePoint.STSADM.Commands.SiteCollectionSettings
12{
13 public class CreateSiteInDB : SPOperation
14 {
15 protected SPWebApplication m_WebApplication;
16
17 /// <summary>
18 /// Initializes a new instance of the <see cref="CreateSiteInDB"/> class.
19 /// </summary>
20 public CreateSiteInDB()
21 {
22 SPParamCollection parameters = new SPParamCollection();
23 parameters.Add(new SPParam("url", "url", true, null, new SPUrlValidator()));
24 parameters.Add(new SPParam("lcid", "lcid", false, "0", new SPRegexValidator("^[0-9]+$")));
25 parameters.Add(new SPParam("sitetemplate", "st", false, null, new SPNullOrNonEmptyValidator()));
26 parameters.Add(new SPParam("title", "t", false, null, null));
27 parameters.Add(new SPParam("description", "desc", false, null, null));
28 parameters.Add(new SPParam("ownerlogin", "ol", false, null, new SPNonEmptyValidator()));
29 parameters.Add(new SPParam("ownername", "on", false, null, null));
30 parameters.Add(new SPParam("owneremail", "oe", true, null, new SPRegexValidator(@"^[^ \r\t\n\f@]+@[^ \r\t\n\f@]+$")));
31 parameters.Add(new SPParam("quota", "quota", false, null, new SPNullOrNonEmptyValidator()));
32 parameters.Add(new SPParam("hostheaderwebapplicationurl", "hhurl", false, null, new SPUrlValidator()));
33 parameters.Add(new SPParam("secondarylogin", "sl", false, null, new SPNullOrNonEmptyValidator()));
34 parameters.Add(new SPParam("secondaryname", "sn", false, null, null));
35 parameters.Add(new SPParam("secondaryemail", "se", false, null, null));
36 parameters.Add(new SPParam("dbname", "db", true, null, new SPNonEmptyValidator(), "Please specify the database name."));
37
38 StringBuilder sb = new StringBuilder();
39 sb.Append("\r\n\r\nCreates a new site collection in an existing content database.\r\n\r\nParameters:");
40 sb.Append("-url <url>");
41 sb.Append("\r\n\t-owneremail <someone@example.com>");
42 sb.Append("\r\n\t[-ownerlogin <DOMAIN\\name>]");
43 sb.Append("\r\n\t[-ownername <display name>]");
44 sb.Append("\r\n\t[-secondaryemail <someone@example.com>]");
45 sb.Append("\r\n\t[-secondarylogin <DOMAIN\\name>");
46 sb.Append("\r\n\t[-secondaryname <display name>]");
47 sb.Append("\r\n\t[-lcid <language>]");
48 sb.Append("\r\n\t[-sitetemplate <site template>]");
49 sb.Append("\r\n\t[-title <site title>]");
50 sb.Append("\r\n\t[-description <site description>]");
51 sb.Append("\r\n\t[-hostheaderwebapplicationurl <web application url>]");
52 sb.Append("\r\n\t[-quota <quota template>]");
53 sb.Append("\r\n\t-dbname <content database name>");
54
55 Init(parameters, sb.ToString());
56 }
57
58 #region ISPStsadmCommand Members
59
60 /// <summary>
61 /// Gets the help message.
62 /// </summary>
63 /// <param name="command">The command.</param>
64 /// <returns></returns>
65 public override string GetHelpMessage(string command)
66 {
67 return HelpMessage;
68 }
69
70 /// <summary>
71 /// Runs the specified command.
72 /// </summary>
73 /// <param name="command">The command.</param>
74 /// <param name="keyValues">The key values.</param>
75 /// <param name="output">The output.</param>
76 /// <returns></returns>
77 public override int Execute(string command, StringDictionary keyValues, out string output)
78 {
79 output = string.Empty;
80
81
82
83 string dbname = Params["dbname"].Value;
84
85 string uriString = Params["url"].Value;
86 string webTemplate = Params["sitetemplate"].Value;
87 string title = Params["title"].Value;
88 string description = Params["description"].Value;
89 string ownerName = Params["ownername"].Value;
90 string ownerEmail = Params["owneremail"].Value;
91 string quota = Params["quota"].Value;
92 string secondaryContactName = Params["secondaryname"].Value;
93 string secondaryContactEmail = Params["secondaryemail"].Value;
94 bool isHostHeaderWebAppUrlTypedIn = Params["hostheaderwebapplicationurl"].UserTypedIn;
95 uint nLCID = uint.Parse(Params["lcid"].Value);
96 Uri uri = new Uri(uriString);
97 SPUrlZone zone = SPUrlZone.Default;
98 bool createActiveDirectoryAccounts = m_WebApplication.WebService.CreateActiveDirectoryAccounts;
99 string ownerLogin = Utilities.TryGetNT4StyleAccountName(Params["ownerlogin"].Value, m_WebApplication);
100 string secondaryContactLogin = null;
101 if (!createActiveDirectoryAccounts || !Params["secondaryemail"].UserTypedIn)
102 {
103 if (!createActiveDirectoryAccounts && Params["secondarylogin"].UserTypedIn)
104 {
105 secondaryContactLogin = Utilities.TryGetNT4StyleAccountName(Params["secondarylogin"].Value, m_WebApplication);
106 }
107 }
108 else
109 {
110 secondaryContactLogin = @"@\@";
111 }
112
113 SPContentDatabase database = null;
114 foreach (SPContentDatabase tempDB in m_WebApplication.ContentDatabases)
115 {
116 if (tempDB.Name.ToLower() == dbname.ToLower())
117 {
118 database = tempDB;
119 break;
120 }
121 }
122 if (database == null)
123 throw new SPException("Content database not found.");
124
125 if (database.MaximumSiteCount <= database.CurrentSiteCount)
126 throw new SPException("The maximum site count for the specified database has been exceeded. Increase the maximum site count or specify another database.");
127
128 SPSite site = null;
129 try
130 {
131 site = database.Sites.Add(uri.OriginalString, title, description, nLCID, webTemplate, ownerLogin,
132 ownerName, ownerEmail, secondaryContactLogin, secondaryContactName, secondaryContactEmail,
133 isHostHeaderWebAppUrlTypedIn);
134
135
136 if (!string.IsNullOrEmpty(quota))
137 {
138 using (SPSiteAdministration administration = new SPSiteAdministration(site.Url))
139 {
140 SPFarm farm = SPFarm.Local;
141 SPWebService webService = farm.Services.GetValue<SPWebService>("");
142
143 SPQuotaTemplateCollection quotaColl = webService.QuotaTemplates;
144 administration.Quota = quotaColl[quota];
145 }
146 }
147 if (!string.IsNullOrEmpty(webTemplate))
148 {
149 using (SPWeb web = site.RootWeb)
150 {
151 web.CreateDefaultAssociatedGroups(ownerLogin, secondaryContactLogin, string.Empty);
152 }
153 }
154 if (isHostHeaderWebAppUrlTypedIn && !m_WebApplication.IisSettings[zone].DisableKerberos)
155 {
156 Console.WriteLine(SPResource.GetString("WarnNoDefaultNTLM", new object[0]));
157 Console.WriteLine();
158 }
159 }
160 finally
161 {
162 if (site != null)
163 site.Dispose();
164 }
165
166 return OUTPUT_SUCCESS;
167 }
168
169 /// <summary>
170 /// Validates the specified key values.
171 /// </summary>
172 /// <param name="keyValues">The key values.</param>
173 public override void Validate(StringDictionary keyValues)
174 {
175 base.Validate(keyValues);
176 string uriString = Params["url"].Value;
177
178 if (Params["quota"].UserTypedIn)
179 {
180 string quota = Params["quota"].Value;
181 SPFarm farm = SPFarm.Local;
182 SPWebService webService = farm.Services.GetValue<SPWebService>("");
183
184 SPQuotaTemplateCollection quotaColl = webService.QuotaTemplates;
185
186 if (quotaColl[quota] == null)
187 {
188 throw new ArgumentException(SPResource.GetString("InvalidQuotaTemplateName", new object[0]));
189 }
190 }
191
192 m_WebApplication = ValidateWebApplication(this);
193 if (m_WebApplication == null)
194 {
195 throw new FileNotFoundException(SPResource.GetString("WebApplicationLookupFailed", new object[] { uriString }));
196 }
197 SPUrlZone zone = SPUrlZone.Default;
198 if (!m_WebApplication.WebService.CreateActiveDirectoryAccounts && !Params["ownerlogin"].UserTypedIn)
199 {
200 throw new ArgumentException(SPResource.GetString("NoADCreateRequiresOwnerLogin", new object[0]));
201 }
202 if (m_WebApplication.GetIisSettingsWithFallback(zone).AuthenticationMode == AuthenticationMode.Windows)
203 {
204 bool bIsUserAccount;
205 if (Params["ownerlogin"].UserTypedIn)
206 {
207 string strLoginName = Utilities.TryGetNT4StyleAccountName(Params["ownerlogin"].Value, m_WebApplication);
208 if (!Utilities.IsLoginValid(strLoginName, out bIsUserAccount))
209 {
210 throw new ArgumentException(SPResource.GetString("InvalidLoginAccount", new object[] { strLoginName }));
211 }
212 if (!bIsUserAccount)
213 {
214 throw new ArgumentException(SPResource.GetString("OwnerNotUserAccount", new object[0]));
215 }
216 }
217 if (Params["secondarylogin"].UserTypedIn)
218 {
219 string strLoginName = Utilities.TryGetNT4StyleAccountName(Params["secondarylogin"].Value, m_WebApplication);
220 if (!Utilities.IsLoginValid(strLoginName, out bIsUserAccount))
221 {
222 throw new ArgumentException(SPResource.GetString("InvalidLoginAccount", new object[] { strLoginName }));
223 }
224 if (!bIsUserAccount)
225 {
226 throw new ArgumentException(SPResource.GetString("OwnerNotUserAccount", new object[0]));
227 }
228 }
229 }
230 }
231
232
233
234
235 #endregion
236
237 internal static SPWebApplication ValidateWebApplication(SPOperation operation)
238 {
239 if (SPFarm.Local == null)
240 {
241 throw new SPException(SPResource.GetString("OperationInvalidInRemoteFarm", new object[0]));
242 }
243 SPWebApplication application;
244 string uriString = operation.Params["url"].Value;
245 bool isHostHeaderWebAppUrlTypedIn = operation.Params["hostheaderwebapplicationurl"].UserTypedIn;
246 Uri requestUri = new Uri(uriString);
247 if ((requestUri.Scheme != Uri.UriSchemeHttps) && (requestUri.Scheme != Uri.UriSchemeHttp))
248 {
249 throw new ArgumentException(SPResource.GetString("InvalidSiteName", new object[] { uriString }));
250 }
251 if (isHostHeaderWebAppUrlTypedIn)
252 {
253 Uri hostHeaderWebAppUrl = new Uri(operation.Params["hostheaderwebapplicationurl"].Value);
254 application = SPWebApplication.Lookup(hostHeaderWebAppUrl);
255 if (application == null)
256 {
257 return application;
258 }
259 bool portMatchFound = false;
260
261 foreach (SPIisSettings iisSettings in application.IisSettings.Values)
262 {
263 foreach (SPSecureBinding secureBinding in iisSettings.SecureBindings)
264 {
265 if (requestUri.Port == secureBinding.Port)
266 {
267 portMatchFound = true;
268 break;
269 }
270 }
271
272 if (!portMatchFound)
273 {
274 foreach (SPServerBinding serverBinding in iisSettings.ServerBindings)
275 {
276 if (requestUri.Port == serverBinding.Port)
277 {
278 portMatchFound = true;
279 break;
280 }
281 }
282 }
283 if (portMatchFound)
284 return application;
285 }
286 Console.WriteLine(SPResource.GetString("HostHeaderDoesNotMatchWebAppPort", new object[0]));
287 Console.WriteLine();
288 }
289 else
290 return SPWebApplication.Lookup(requestUri);
291
292 return application;
293 }
294
295 }
296}
The syntax of the command can be seen below:
C:\>stsadm -help gl-createsiteindb
stsadm -o gl-createsiteindb
Creates a new site collection in an existing content database.
Parameters:
-url <url>
-owneremail <someone@example.com>
[-ownerlogin <DOMAIN\\name>]
[-ownername <display name>]
[-secondaryemail <someone@example.com>]
[-secondarylogin <DOMAIN\\name>
[-secondaryname <display name>]
[-lcid <language>]
[-sitetemplate <site template>]
[-title <site title>]
[-description <site description>]
[-hostheaderwebapplicationurl <web application url>]
[-quota <quota template>]
-dbname <content database name>
The following table summarizes the command and its various parameters:
Command Name | Availability | Build Date |
---|---|---|
gl-createsiteindb | WSS 3, MOSS 2007 | Released: 1/31/2008, Updated: 4/30/2009 |
Parameter Name | Short Form | Required | Description | Example Usage |
---|---|---|---|---|
url | Yes | The URL to the site collection to create. | -url "http://portal/sites/NewSite" | |
owneremail | oe | Yes | The site owner’s e-mail address. Must be valid e-mail address, in the form someone@example.com. | -owneremail someone@example.com , -oe someone@example.com |
ownerlogin | ol | If your farm does not have Active Directory account creation mode enabled, then this parameter is required. This parameter should not be provided if your farm has Active Directory account creation mode enabled, as Microsoft Office SharePoint Server 2007 will automatically create a site collection owner account in Active Directory based on the owner e-mail address. | The site owner’s user account. Must be a valid Windows user name, and must be qualified with a domain name, for example, domain\name | -ownerlogin domain\name , -ol domain\name |
ownername | on | No | The site owner’s display name. | -ownername "Gary Lapointe" , -on "Gary Lapointe" |
secondaryemail | se | No | The secondary site owner’s e-mail address. Must be valid e-mail address, in the form someone@example.com. | -secondaryemail someone@example.com , -se someone@example.com |
secondarylogin | sl | If your farm does not have Active Directory account creation mode enabled, then this parameter is required. This parameter should not be provided if your farm has Active Directory account creation mode enabled, as Microsoft Office SharePoint Server 2007 will automatically create a site collection owner account in Active Directory based on the owner e-mail address. | The secondary site owner’s user account. Must be a valid Windows user name, and must be qualified with a domain name, for example, domain\name | -secondarylogin domain\name , -sl domain\login |
secondaryname | sn | No | The secondary site owner’s display name. | -secondaryname "Pam Lapointe" , -sn "Pam Lapointe" |
lcid | No | A valid locale ID, such as “1033” for English. You must specify this parameter when using a non-English template. | -lcid 1033 | |
sitetemplate | st | No | Specifies the type of template to be used by the newly created site. The value must be in the form name#configuration. If you do not specify the configuration, configuration 0 is the default (for example, STS#0). The list of available templates can be customized to include templates you create. | -sitetemplate STS#0 , -st STS#0 |
title | t | No | The title of the new site collection | -title "New Site" |
description | desc | No | Description of the site collection. | -description "New Site Description" , -desc "New Site Description" |
hostheaderwebapplicationurl | hhurl | No | A valid URL assigned to the Web application by using Alternate Access Mapping (AAM), such as “http://server_name”. When the hostheaderwebapplicationurl parameter is present, the value of the url parameter is the URL of the host-named site collection and value of the hostheaderwebapplicationurl parameter is the URL of the Web application that will hold the host-named site collection. | -hostheaderwebapplicationurl http://newsite , -hhurl http://newsite |
quota | No | The quota template to apply to sites created on the virtual server. | -quota Portal | |
dbname | db | Yes | The name of the Microsoft SQL Server database or Microsoft SQL Server 2000 Desktop Engine (Windows) (WMSDE) database used for Windows SharePoint Services data. | -dbname SharePoint_Content1 , -db SharePoint_Content1 |
Here’s an example of how to create a site in an existing content database:
stsadm -o gl-createsiteindb -url "http://intranet/sites/testsite1" -owneremail "someone@domain.com" -ownerlogin "domain\someone" -ownername "Some User" -sitetemplate "BLANKINTERNET#2" -title "Test Site" -dbname "SharePoint_ContentDB1"
Update 4/30/2009: I’ve updated the code so that it now creates the default site groups for the site collection.