Power of PowerShell and the SharePoint Snap-in

Recently I started to look into some more detail at PowerShell and the SharePoint 2010 Snap-in. As a small exercise I wanted to create something (somewhat) usefull.

I came up with a small site structure install script for SP2010.

First the source configuration, an xml, with the sites and subsites I wanted to created:

<?xml version="1.0" ?>
<site title="Test Portal" template="STS#0" lcid="1033" owner="sp2010\administrator">
    <features>
        <feature id="{22a9ef51-737b-4ff2-9346-694633fe4416}"/>
        <feature id="{f6924d36-2fa8-4f0b-b16d-06b7250180fa}"/>
        <feature id="{94c94ca6-b32f-4da9-a9e3-1f3d343d7ecb}"/>
    </features>
    <webs>
        <web url="Subsite1" title="Subsite 1" template="STS#0" lcid="1033" />
        <web url="Subsite2" title="Subsite 2" template="STS#0" lcid="1033">
             <webs>
                <web url="SubSubsite1" title="SubSubsite 1" template="STS#0" lcid="1033" />
                <web url="SubSubsite2" title="SubSubsite 2" template="STS#0" lcid="1033" />
            </webs>
        </web>
        <web url="Subsite3" title="Subsite 3" template="STS#0" lcid="1033">
            <webs>
                <web url="SubSubsite1" title="SubSubsite 1" template="STS#0" lcid="1033" />
                <web url="SubSubsite2" title="SubSubsite 2" template="STS#0" lcid="1033" />
            </webs>
        </web>
     </webs>
</site>

Next I wrote two helper function inside my PowerShell script:

function ActivateFeatures([System.Xml.XmlNode]$node){
    #features for current web
    $features = $node.selectnodes("./features/feature") # XPath is case sensitive
    foreach ($feature in $features) {
        $fid= $feature.getAttribute("id")
        write-host -f blue "Activating Feature $fid at $baseurl"
        Enable-SPFeature -Identity "$fid" -Url $baseurl -Force
    }
}

function ParseNode([System.Xml.XmlNode]$node){
    $url = $node.getAttribute("url")
    $title = $node.getAttribute("title")
    $lcid = $node.getAttribute("lcid")
    $template = $node.getAttribute("template")
    $baseurl = "$baseurl$url"

    write-host -f red "Going to create site at: $baseurl with Title: $title"
    New-SPWeb -Url "$baseurl" -Name $title -Template $template -Language $lcid

    ActivateFeatures($node);

    # add a trailing slash to create urls
    $baseurl = "$baseurl/"

    # sub webs
    $subnodes = $node.selectnodes("./webs/web") # XPath is case sensitive
    foreach ($subnode in $subnodes) {
        ParseNode($subnode)
    }
}

First remove the existing site collection:

$baseurl ="http://portal.sp2010.com"
Write-Host -f Red "Removing Site Collection at $baseurl"
Remove-SPSite $baseurl

And then start reading the xml file and start creating a site collection

write-host -f green "Opening sites.xml"

[System.Xml.XmlDocument] $xd = new-object System.Xml.XmlDocument
$file = resolve-path("./sites.xml")

$xd.Load($file)

#site collection
$sitenode = $xd.selectsinglenode("/site") # XPath is case sensitive
$title = $sitenode.getAttribute("title")
$lcid = $sitenode.getAttribute("lcid")
$template = $sitenode.getAttribute("template")
$owner = $sitenode.getAttribute("owner")

write-host -f red "Creating Site Collection at $baseurl"
New-SPSite -Url "$baseurl" -Name $title -Template $template -Language $lcid -OwnerAlias $owner
ActivateFeatures($sitenode);

# add a trailing slash to create urls
$baseurl = "$baseurl/"

# subwebs
$nodelist = $xd.selectnodes("/site/webs/web") # XPath is case sensitive
foreach ($node in $nodelist) {
    ParseNode($node)
}

write-host "End of sites.xml"

And add this to the top of your SP2010 PowerShell Script to always load the Snap-in.

$snapin="Microsoft.SharePoint.PowerShell"
if (get-pssnapin $snapin -ea "silentlycontinue") {
    write-host -f Green "PSsnapin $snapin is loaded"
}
elseif (get-pssnapin $snapin -registered -ea "silentlycontinue") {
    write-host -f Green "PSsnapin $snapin is registered"
    Add-PSSnapin $snapin
    write-host -f Green "PSsnapin $snapin is loaded"
}
else {
    write-host -f orange "PSSnapin $snapin not found" -foregroundcolor Red
}

You can download both files here: codeplex.com

Advertisements

3 Responses to “Power of PowerShell and the SharePoint Snap-in”

  1. Paul Cassidy Says:

    you can simplify the code as xmldocument is a native type to powershell.

    Replace:

    [System.Xml.XmlDocument] $xd = new-object System.Xml.XmlDocument
    $file = resolve-path(“./sites.xml”)
    $xd.Load($file)

    With:

    [xml]$xd = get-content (resolve-path “./sites.xml”)

  2. Paul Cassidy Says:

    also you can replace all the $node.SelectNode with select-xml wich take a xpath expression to return the node or nodes you want. over all I really like the example of someone using the Sharepoint snapin as i am going to look into it soon.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: