Updating SharePoint 2010 site properties

 

Recently I helped convert a SharePoint farm to the 2010 version from 2007. The SharePoint user interface has substantial changes between the two versions, so to make it easier on the end users, Microsoft allows sites to keep the 2007 look and feel. Once you migrate a farm with sites that are in the 2007 look and feel, you can upgrade the sites to the 2010 look and feel at your convenience, when the end user is well prepared. So that's what we did, and now I'm converting a small number of sites to the 2010 look and feel every day.

Microsoft makes it possible to convert sites to the new look and feel through the web browser, but it involves a lot of clicks and is prone to errors. So I wrote a PowerShell script to change the UIVersion property on a site. I've been running this script, converting sites, with no problems. Then today I found out that the script hasn't been fully converting sites to the 2010 look and feel, it's been converting them to the 2010 preview, which includes a yellow reminder bar in the settings pages to fully convert the site to 2010. It turns out you need to set UIVersionConfigurationEnabled = $false in addition to UIVersion = 4 to not convert to the preview mode.

So here's my quick and dirty one-liner to loop through all the site collections, then loop through all the sites in each site collection and fixes any site with UIVersion of 4 and UIVersionConfigurationEnabled = $true. I've added line breaks to my script to make it more readable, but when I was writing it I just typed this as one line in the SharePoint 2010 PowerShell Management Shell.

I love the pipeline concept in PowerShell. It's a very functional concept - each stage of the pipeline gets a collection of objects passed to it, operates on those objects, and passes the results to the next stage in the pipeline. So the script starts by gathering all the site collections, then it uses those to find all the sites, and then it uses the Where-Object cmdlet to filter out only the matching sites. The last stage of my pipeline is where PowerShell breaks the functional model, because the Foreach-Object cmdlet directly updates the sites, but breaking the functional model here makes writing PowerShell scripts so much easier. If I had to create a copy of the sites and then send that copy to a IO function, that would add unnecessary complexity to what is a very useful language for quickly modifying collections of things.

Get-SPSite -limit ALL | 
        Get-SPWeb -Identity $_ -limit ALL | 
            Where-Object { 
                $_.UIVersion -eq 4 -and 
                $_.UIVersionConfigurationEnabled -eq $true 
            } | 
                Foreach-Object { 
                    $_.UIVersionConfigurationEnabled = $false; 
                    $_.update() 
                }