Although the arguments to New-SPWeb are simple, it is possible to do much more with a web than that. And some arguments are shortcuts to 'real' objects. For example, 'owners' become proper SPUser objects.

What I'm trying to say, is that we need to read the structure the hard way, collecting properties and creating the xml structure along the way. It is not difficult. A few things might be worth pointing out.

Portnumber

When creating a new webapp, we specify which port number we should use. This is a typical example of how something is easy to create, but difficult to read.

Template

Web templates is a new feature in SharePoint 2010. For an excellent and through introduction visit Vesa Juvonen's blog.

Web templates supposedly inherit a site definition. I say supposedly; the only thing it seems to inherit is the site definition ID. That is, if you 'get' the template ID of a web created using a web template, you'll typically get "STS#0". Which isn't particularily useful, as you typically want the web template ID - which has the format of {guid}#templatename.

Vesa's blog strongly suggests saving the web template name to the web's property bag. The Get-Template method supports this, and also the 'full' name.

function GetTemplate($web){ # if it is a web template which was made following Vesa's recipe, the webtemplateid is stored in the property bag. $webId = $web.AllProperties["WebTemplateId"] if ($webId -ne $null) { if ($webId.Contains('#')) { # presumably GUID#Name - which is what we want return $webId } # sigh. Try to find the template itself. (it may not work; just because # a web is of type A, that may (no longer) be an allowed webtemplate) # we're looking for a webtemplate which contains the name $wt = $web.GetAvailableWebTemplates([int]$web.Language) | Where-Object { $_.Name.Contains($webId) } return $wt.Name } $wtName = $web.WebTemplate $wtId = $web.WebTemplateId return "$($wtName)#$($wtId)"}

Url

As mentioned in the previous post, I want to use the hierarchical structure of xml to help create urls. If an element specifies “news,” rather than “http://server/dept1/news”, I can easily copy-paste-move it between branches and levels.

But how do we know what to save?

One huge problem with this part of the solution, is that it is tightly coupled to the farm we’re analyzing, in that we only read the things we know we’re interested in. And that varies a lot.

One of the servers where I tried this mechanism had a mix of English and Norwegian sites. When collecting this information, I only ‘save’ the setting if it is different from English.

Perhaps a similar approach may be taken for other things that language? Only save if different from default.

But two problems remain: What are the defaults? And what are the parameters we need to query? (even as I write this, I realize that the second question may be solved through some creative use of “Get-Member”) (Hm)