MOSS MVP

I've moved my blog to http://blog.falchionconsulting.com!. Please update your links. This blog is no longer in use--you can find all posts and comments at my new blog; I will no longer be posting to this site and comments have been disabled.

Thursday, January 31, 2008

Create Site in Database

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:

   1: using System;
   2: using System.Collections.Specialized;
   3: using System.IO;
   4: using System.Text;
   5: using System.Web.Configuration;
   6: using Lapointe.SharePoint.STSADM.Commands.SPValidators;
   7: using Microsoft.SharePoint;
   8: using Microsoft.SharePoint.Administration;
   9: using Lapointe.SharePoint.STSADM.Commands.OperationHelpers;
  10:  
  11: namespace 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.

34 comments:

Greg said...

Hey Gary,

Just wanted to thank you for the wonderful stsadm additions you created. I needed to complete just this exact job, and was not looking forward to coding a simple .net app just to do it. Being able to create site collections in a particular database from the command line is completely invaluable.

Thanks so much!

Geoff said...

Gary,

Great work on this command, very helpful for letting us put the site where we want them. However, is there any way it can (hopefully easily) be extended to allow for some of the newsbweb.aspx functionality, including inherit permissions and inherit top nav bar?

We're working on a US Government deployment, and batching the creation of the sites would be very helpful.

Gary Lapointe said...

The features you're looking for would be more specific to a createweb command - you can do some of what you want with the setnavigationsettings command but it won't help you with security.

Anonymous said...

Hi Gary,
Very nice extensions and realy make the task simple and would like to know if we can have same thing to do via object modal is it feasible?

Gary Lapointe said...

You can download the source to the commands and right your own app using the code (which of course uses the object model). I'm planning on creating PowerShell scripts for some of my commands in the future but just haven't had time.

Jason Walters said...

Gary,

There is a problem with your gl-createsiteindb command. If you create a site collection with it and then try to activate publishing infrastructure for that site collection it complains that other features are not activated. But if I create a site collection using the normal stsadm createsite command I do not see this issue.

TJ said...

Hi Gary,

What is your recommendation for using the functionilty of your STSADM commands from custom script?

Currently from an event receiver which will be used for provisioning sites I wish to use this command. Should I call it simple using the command? Or would you suggest I use the source instead reimplemented in my custom project?

Thanks for your thoughts.

Gary Lapointe said...

TJ - It really just depends on whether or not you want to have the dependency - this particular command hasn't been abstracted out so that it could be easily called directly but you could write something that calls out to stsadm. If you're good with code I'd say just pull what you need and refactor per your needs.

Andrew said...

Gary

First off, thanks very much for all your ahrd work with these commands - brilliant work.
I'm having a bit of an issue with this one - when trying to create the site in the database I get the error "the quote template name entered is invalid"

I am not using the -quota option at all (it looks as if it should be optional?) and I don't want a quota on this site - in fact I don't have any quota templates set up, when I create a site through the GUI, I leave the "No Quota" default set.

Gary Lapointe said...

Andrew - I forgot to wrap the quota validation check in a parameter presence check - I've added that code and republished - let me know if you have any further issues with this.

vgurusam said...

Gary,

I was reading your blog regarding the creating site collection in existing content database. Really appreciate the job you had done in extending these stsadm commands.
I’m trying to use the same command in a Sharepoint Object model as you used in your sample code in the following link:

http://stsadm.blogspot.com/2008/01/create-site-in-database.html

I was not sure what are the references you added so that you have access to Utilities class since its declared internal in the namespace: Lapointe.Sharepoint.STSADM.Commands.OperationHelpers

I did add reference to the following dll: Lapointe.Sharepoint.STSADM.Commands and then included the namespace for OperationHelpers you mentioned above but I did have access to the Utilities since it was declared internal.

Please let me know how do I approach this problem to create site collection in existing database through Sharepoint object model.

Gary Lapointe said...

Just pull the stuff you need from the utilities class out into your own project - I'd prefer people not reference that class directly as I often make changes to the signatures of those methods and don't want people to be dependent on them. One word of caution - to do what I did you have to use reflection to gain access to an internal method - there is no public method for creating a site collection in a specific database - the alternative approach (and I may change my code to do this) is to mark all the content databases max sites property to be equal to the number of current sites (with the exception of the db you want your site in) and then call the public methods provided.

Anonymous said...

Gary,
We have a site collection (MySites) and we do not want any database to grow to more than 100 GB. Given that I need to add additional databases to this site collection. Is there a command that will allow me to assign multiple databases to one site collection?

Gary Lapointe said...

A site collection can exist in one and only one content database. If it's your mysites that you are talking about then I'd recommend setting a quota to something small and then set the max number of site collections in the content database to prevent the 100gb from being exceeded (so if your quota is 1gb then set the max site count to 100 (actually something less as you have to take into account the second stage recycle bin settings)). You can then add more content databases if you need more sites.

tripwire said...

Hi Gary,

Many times I have a siutation where I'd like to import/restore a site to a specific DB.

You creatsitecollectionfrom subsite command allows a -filename parameter. I don't suppose you'd be willing to do the same here?

Gary Lapointe said...

Just create an empty site collection (no template specified) - you can then import into this site collection.

arun said...

Hi Gary,

This is a really awesome command.
I see a provision to select the database name (-dbname). I have a requirement where in i have to create many site collections by distributing them across many SQL servers. Is there a way to provide the SQL server name and login details????

Thanks in advace,
Arun G

Gary Lapointe said...

Use my gl-createcontentdb command to create the database first, then use the gl-createsitindb command to add the site to that content database.

Ryan said...

The default createsiteinnewdb command works fine if you manage your content databases correctly in central administration. by default, the createsiteinnewdb command will create the sitecollection in the most recently created content db, unless it has either

A: The "database status" of all the databases except the one you wish to have your site collection created in have been set to offline.

B:if you modify the database capacity settings of the db's to the correct number of sites you wish to have in each.
For example: lets say you have 3 web applications and content databases. and you want to add an additional content db to one of these web applications. In order to have one site collection in each content db go to your central admin > manage content database settings> (perform this for each web application)
set the database capacity settings to 0 before warning, and 1 maximum number of sites.
Now go to defined managed paths, and choose the web application that you wish to add an extra site collection to (with seperate db) and enter the name of this site collection, and choose explicit inclusion.

Now navigate to 12 hive and enter stsadm.exe -o createsiteinnewdb -url http://testsite.blah.com/sitecollectionnameyoujustdefined -ownerlogin domain\username -owneremail bob@domain.com -databasename 123db

Once it finishes - browse to the url and you should be able to access your site.

You must also go back and change the database capacity settings on the newly created database so the next time a site collection is added it won't get put into that db.

In my setup, i have about 10 webapp's setup, however for one project we wanted one url to go to for a series of sites, however depending on storage and backup requirements, we needed to seperate content db's out on a per site basis. for larger sites i create individual site content db's using the above command, otherwise if i want to add additional site collection to an existing content db, i just raise the max site allowance in the catchall content db that holds all smaller site collections under this one url. Every time i want to add a new site, i just increase this value by one, so once you created the new site, the content db capacity will be back up to the maximum value.


Ryan Klick

tripwire said...

"Just create an empty site collection (no template specified) - you can then import into this site collection."

I could do that. But then how do I specify the database name?

Gary Lapointe said...

It's a parameter on the command (-databasename).

tripwire said...

Oh I see wht you mean. The db is already associated with the site and so will use the correct one. Didn't realise that. :)

tripwire said...

I think one of is getting confused. The gl-createsiteindb command has a -databasename parameter. But only allows you to create a new site collection, not specify a backup file.

I didn't realise that not specifying a sitetemplate would create a blank site collection. Nor did I realise that, once created, the database would remain attached to that collection for subsequent restore jobs.

Michael said...

Hey Gary,

i get an Access Denied Error when using your command... Do you have any idea why?
Here is the errot:
Access Denied (HRESULT: 0x80070005 (E_ACCESSDENIED))

is use the command as admin..

Thanks for your Help!

Regards
Michael

Michael said...

Hi Gary its me again..

as i can see he sitecollection is created but there are no groups added... Maybe this helps...

Regards
Michael

Gary Lapointe said...

Make sure you're running the command as a farm admin.

Michael said...

Gary, thanks for your quick answer!
I run the command as Farmadmin! Do you have any other ideas?

Regards
Michael

Gary Lapointe said...

Does the out of the box createsite or createsiteinnewdb command work for you? I've honestly never seen this issue before - only time I've ever seen access denied issues was when running with the wrong account and usually it doesn't actually create anything (the fact that it created the site but not the accounts is very odd).

tripwire said...

Curiously enough I identified this problem yesterday with our third party developer.

At first we thought it was a problem in the provisioing code for our site template but it's only happening when creating sites through stsadm - including OOTB commands.

No default groups. No errors. No events. Just the usual "Operation complete". It also look slike any remaning tasks are not completed.

Creating sites through CA, or webs via the front end, works as expected.

If this does turn out to be permissions related (which it appears to be) I'd love to know the resolution.

tripwire said...

@Michael

Gary, you actually answered this in another post on 30 April. :)

http://stsadm.blogspot.com/2009/04/creating-default-site-groups-after.html

c_marius said...

Hi Garry,
I've noticed in your code that you are using Farm as the basis for your retrieve available Quota templates. Is there any particular reason why not using the WebApplication.Service...etc...for it??

Gary Lapointe said...

I guess it's just because quota templates are a farm wide setting so I prefer to get to it via the farm and not the webapplication objects - either way it doesn't really matter, just a question of convention.

Anonymous said...

I've used this in 2007 and really liked it. Is this available for 2010? I know MS has the new-spsite to target contentdb however I found it not doing a good job creating groups.

Thanks!

Gary Lapointe said...

I don't currently have it for 2010 but I may add it in.