Microsoft SharePoint 2010 and Windows PowerShell 2.0: Expert Cookbook
上QQ阅读APP看书,第一时间看更新

Provisioning site hierarchy during solution deployment

In this recipe, we'll give full attention to one of the most common tasks administrators and developers need to perform together when a new solution is deployed to client environments: provisioning of site hierarchy. To keep this recipe within the scope of actual site provisioning and not custom site template development, we will be provisioning a site hierarchy of team sites. In your scenario, you are very likely to need to provision site hierarchy of sites deriving from a custom site template. The template will be developed separately and the PowerShell script we'll create here will not change regardless of the templates we're provisioning.

In fact, the PowerShell script we'll create is going to use an XML file where developers will specify the order of the site provisioning and site template used, as well any features activated on the site once it's created.

At the end of this recipe, you will have a reusable script which you can use on many other projects, as well as being able to extend it to facilitate any additional deployment needs you may have.

Getting ready

We'll assume you have already set up your virtual development environment as described in Chapter 1, PowerShell Scripting Methods and Creating Custom Commands. We'll also assume you're comfortable with using tools we discussed in the chapter. For this recipe, we'll be using PowerGUI to author the script.

How to do it...

Let's take a look at how site and content provisioning can be accomplished with the script in this recipe:

  1. On the target Virtual Machine, ensure you are logged in with an administrator's role.
  2. Click Start | All Programs | PowerGUI | PowerGUI Script Editor.
  3. In the main script editing window of PowerGUI, add the following script:
    # Defining script variables
    [xml]$SiteStructure = get-content SiteStructure.xml
    $WebAppUrl = $SiteStructure.Setup.Attributes.Item(0).Value
    $SiteCollectionUrl = $SiteStructure.Setup.SiteCollection.Attributes.Item(1).Value
    $SiteUrl = $WebAppUrl + $SiteCollectionUrl
    # Loading Microsoft.SharePoint.PowerShell
    $snapin = Get-PSSnapin | Where-Object {$_.Name -eq 'Microsoft.SharePoint.Powershell'}
    if ($snapin -eq $null) {
    Write-Host "Loading SharePoint Powershell Snapin"
    Add-PSSnapin "Microsoft.SharePoint.Powershell"
    }
    # Deleting existing site found at target URL
    $targetUrl = Get-SPSite | Where-Object {$_.Url -eq $SiteUrl}
    if ($targetUrl.Url.Length -gt 0) {
    Write-Host "Deleting existing site at" $SiteUrl
    Remove-SPSite -Identity $SiteUrl -Confirm:$false
    }
    # Creating site structure
    $SiteCollectionName = $SiteStructure.Setup.SiteCollection.Attributes.Item(0).Value;
    $SiteCollectionOwner = $SiteStructure.Setup.SiteCollection.Attributes.Item(2).Value;
    $SiteCollectionTemplate = $SiteStructure.Setup.SiteCollection.Attributes.Item(3).Value;
    Write-Host "Creating new site collection at" $SiteUrl
    $NewSite = New-SPSite -URL $WebAppUrl$SiteCollectionUrl -OwnerAlias $SiteCollectionOwner -Template $SiteCollectionTemplate -Name $SiteCollectionName
    $RootWeb = $NewSite.RootWeb
    Write-Host "Site collection created successfully"
    Write-Host "Title:" $RootWeb.Title -foregroundcolor Green
    Write-Host "URL:" $RootWeb.Url -foregroundcolor Green
    Write-Host "-------------------------------------"
    for ($i=1; $i -lt $SiteStructure.Setup.SiteCollection.ChildNodes.Count; $i++ )
    {
    $childsite = $SiteStructure.Setup.SiteCollection.ChildNodes.Item($i);
    $WebName = $childsite.Attributes.Item(0).Value
    $WebUrl = $childsite.Attributes.Item(1).Value
    $WebTemplate = $childsite.Attributes.Item(2).Value
    Write-Host "Creating new web at" $SiteUrl/$WebUrl
    $NewWeb = New-SPWeb $SiteUrl/$WebUrl -Template $WebTemplate -Addtotopnav -Useparenttopnav -Name $WebName
    Write-Host "Web created successfully"
    Write-Host "Title:" $NewWeb.Title -foregroundcolor Green
    Write-Host "URL:" $NewWeb.Url -foregroundcolor Green
    Write-Host "-------------------------------------"
    }
    start-process -filepath iexplore -argumentlist $SiteUrl
    
  4. Click File | Save to save the script to your development machine's desktop. Set the filename of the script to setup.ps1.
  5. Click File | New in PowerGUI application.
  6. Add the following code in the newly opened file window:
    <Setup WebAppUrl="http://intranet.contoso.com">
    <SiteCollection Name="Root Site" Url="/sites/rootsite" OwnerAlias="contoso\administrator" Template="STS#0">
    <Site Name="Child 1" Url="child1" Template="STS#0"/>
    <Site Name="Child 2" Url="child2" Template="STS#0"/>
    <Site Name="Child 3" Url="child3" Template="STS#0"/>
    </SiteCollection>
    </Setup>
    
  7. Save the file on your desktop by clicking File | Save providing the following filename: SetupStructure.xml.
  8. Open the PowerShell console window and call setup.ps1 using the following command:
    PS C:\Users\Administrator\Desktop> .\setup.ps1 
    
  9. As a result, your PowerShell script will create a site structure as shown in the following screenshot:
  10. Observe the Internet Explorer window opening and navigate to our newly created site collection with URL: http://intranet.contoso.com/sites/rootsite.

How it works...

The automated site provisioning process we created above consists of two parts: a PowerShell script executing the commands, and the XML defining our site structure.

Let's take a look at the XML containing the site structure definition. The top element,<Setup/>, defines the web application URL which is used to connect to the site and create new site collection.

<SiteCollection/> is the next node in the XML which defines parameter values required for the script to create a new site collection on the specified web application.

The last item in the XML definition is the<Site/> node defining the sites which are going to be created under the site collection. Some of the other parameters required for the site creation are also captured here. These parameters include the URL, name, and the template. In our recipe example, we're using the STS#0 template which is a Team Site.

Let's take a look at the actual PowerShell provisioning script. First, the script gets a hold of the XML file defining provisioning variables we just looked at. The structure of the XML is parsed to extract the variables from SiteStructure.xml.

Once the PowerShell snap-in has been loaded, the script proceeds in creating a site collection defined in the<SiteCollection/> node. The existing site collection with the same URL will be deleted. This may not be the behavior you would like to implement to avoid site deletion in error, in which case remove the following code:

# Deleting existing site found at target URL
$targetUrl = Get-SPSite | Where-Object {$_.Url -eq $SiteUrl}
if ($targetUrl.Url.Length -gt 0) {
Write-Host "Deleting existing site at" $SiteUrl
Remove-SPSite -Identity $SiteUrl -Confirm:$false
}

By removing this code, if an existing site collection exists on the URL provided, the provisioning of the site collection will fail.

Once site collection has been provisioned, any associated sites under the site collection will be provisioned.

As a result, when the provisioning is complete, the following is the resulting site collection with child sites created in it: http://intranet.contoso.com/sites/rootsite , as seen in the following screenshot:

See also

The Installing features on the site and managing existing site features recipe in this chapter.