Tuesday, May 28, 2013

Using PowerShell to Create a New Site Collection with a Custom Site Template Definition and/or Template

OK –

Despite the help from google, this one had stumped for the better half of two hours -

To expedite development efforts i will always use automation techniques to avoid mundane and repetitive tasks.  i.e. – Developing/troubleshooting/Testing the activation of a feature with declarative xml and/or feature receiver as well as provisioning of a custom site definitions .

in the example above I’d simply have a script to:

  1. Delete an existing Site Collection (always handy if you have declarative content types – you don’t want existing features/deployments getting in your way)
  2. Create a new site collection
  3. Activate any features as required

Depending on what you’re doing, you don’t always need to redeploy the solution or even re-create the site collection – so there’s always benefit to adding a few flags at the top of the script to control execution and save costly wsp retractions/redeployments (subsequently resulting in costly app pool recycles), IIS Resets (even more costly) and site collection / sub web provisioning (which can take some time for those complex definitions involving multiple sub webs / lists and/or libraries).

A good SharePoint developer knows where to cut corners in terms of general development/deployment techniques – productivity is key in working with this platform.  If you can avoid an App Pool Recycle and/or IIS Reset with code deployments you can easily save 20 seconds per incremental deployment.  A focused developer will see one of these at least every two minutes.  30 per hour * 8 = 240.  240 deployments @ 20 seconds = 4800 seconds = 80 minutes.  You could have left yesterday at 3.40! :)

Anyway – off topic –

For this post I'd opened said PowerShell prompt a long long time ago (possibly weeks even?? – seeing as though i rarely restart my dev vms – this is more than possible).  After numerous attempts of creating/deploying my custom site definition and getting sick of creating a new site collection through the UI i looked into a programmatic provision. 

I tried the standard:

new-spsite –url http://url/sites/blah –owneralias domain\username –template TemplateName#ID –name siteName

This didn’t work :(

(it failed saying it couldn’t locate the template)

after a bit of googling, i was led down the garden path in needing to get a random guid based on the fact it was a custom template.  I tried numerous methods of getting web templates without success:

SPSite.GetWebTemplates(UInt32);

SPSite.GetCustomWebTemplates(UInt32);

SPWeb.GetAvailableWebTempaltes(UInt32);

SPWeb.GetAvailableWebTempaltes(UInt32, Bool);

SPWeb.GetAvailableCrossLanguageTemplates();

SPWeb.GetCatalog(SPListTemplateType);

None of these returned any indication of my custom site definition (yet i know it was there as I'd previously successfully created it through the central admin UI).

Anyway -

short of the story is -

PowerShell (and more accurately, the SharePoint Snap In) happens to cache the available web templates per web application when the first site/web within said web app is referenced.

Simply closing the PowerShell console, opening a new one and re-adding the snap-in allowed me to see (and more importantly create new sites from) the custom site definition. 

What’s more – didn’t have to worry about any of the guid based referencing of the template that is common in Google.  Seeing as though I've developed it as a traditional / full site definition there’s been no random guid associated with the template and I'm able to reference it as I've declared in the webtemp file.

2 comments:

  1. Here are the steps;

    Write-Host $web.GetAvailableWebTemplates(1033) - to get your custom site template name and then try the following code to get the new site created using the 'Applywebtemplate' method.


    #Get the custom site template name
    $sitetemplateName = "{594E8A0A-30E5-4ADE-9727-4520160EFFE3}#TestTemp"
    $spWeb = New-SPWeb -Url $spSiteUrl/$parentUrl/$subUrl -Name $siteName
    write-host "Applying custom template..."
    $spweb.ApplyWebTemplate($sitetemplateName)
    $spweb.update()

    This gets tricky if you try any other way....

    Cheers
    Kumar

    ReplyDelete
  2. Thank you!

    This solved my problem.

    Keeps me wondering why I didn't try turning it off and on again in first place... :-)

    ReplyDelete