Upgrade a SharePoint 2010 solution with features using Power Shell

Having finished the first three SharePoint 2010 portals with our team, we have come across the inevitable need to change certain things in an already running website. Since we obviously cannot retract, uninstall, reinstall and redeploy our solutions (the data would be lost), we have started looking into the upgrade process in SharePoint 2010. After having gained a lot of knowledge from this blog post by Chris O’Brien, we were ready to deploy our upgrades.

In his blog, Chris describes his SharePoint Feature Upgrade Kit, which provides a very handy way to graphically upgrade features, as well as to do the same by using Power Shell. However, even using the Power Shell version of his tools requires installing a few things to the GAC, which we would prefer not to have to ask our maintenance team. So we have set out to make some simple Power Shell scripts of our own which we can just put in a .ps1 file to give to our administrators. As Chris notes, there are no built-in commands to upgrade features easily, so we have to do this the ‘hard’ way ;)

This script will upgrade one SharePoint solution and then upgrade all of the features (both site and web scoped) it contains on the given SPSite.

$# Solution upgrade script
# 
# Author: Olaf Keijsers
# Date:   02/15/2011
#
# Upgrades a solution, then upgrades all site and web scoped features 
# on the given URL.
#
# Usage:
# Enter correct values for the $wspFile, $path and $siteUrl variables, 
# then run the script from a SharePoint admin shell. Somehow only 
# works once when run in a new instance of Power Shell.

$wspFile = "name_of_old_wsp_file.wsp";
$path    = "C:\Path\To\WSP\new_wsp_file.wsp";
$siteUrl = "http://site.url:port";

Write-Host "Upgrading solution:" $wspFile -ForegroundColor Green;
Update-SPSolution -Identity $wspfile -LiteralPath $path -GACDeployment ;
$solution = Get-SPSolution $wspFile ;
Write-Host "Waiting for solution upgrade to complete" -NoNewline;

while ($solution.JobExists -eq $true) {
    Write-Host "." -NoNewline;
    sleep 1;
    $solution = Get-SPSolution $wspFile ;
}
""
Write-Host "Solution upgrade completed." -ForegroundColor Green;
""
Write-Host "Upgrading site features for site:" $siteUrl -ForegroundColor Green;
$site = Get-SPSite -Identity $siteUrl ;
$count = 0;
$features = $site.QueryFeatures("Site", $true);
Foreach($feature in $features) {
    if ($feature.Definition.SolutionId -eq $solution.Id) {
        $oldVersion = $feature.Version;
        Write-Host "Upgrading feature:" $feature.Definition.DisplayName;
        Write-Host "  Current version:" $oldVersion;
        $feature.Upgrade($true);
        $newVersion = $feature.Version;
        Write-Host "      New version:" $newVersion;
        if ($oldVersion -eq $newVersion) {
            Write-Host "  Something went wrong upgrading this feature!" -ForegroundColor Red;
        } else {
            Write-Host "  Upgrade successful." -ForegroundColor Green;
            $count++;
        }
    }
}
""
Write-Host "Updating web scoped features:" -ForegroundColor Green;
$features = $site.QueryFeatures("Web", $true);
Foreach($feature in $features) {
    if ($feature.Definition.SolutionId -eq $solution.Id) {
        $oldVersion = $feature.Version;
        Write-Host "Upgrading feature:" $feature.Definition.DisplayName;
        Write-Host "              Web:" $feature.Parent.Url;
        Write-Host "  Current version:" $oldVersion;
        $feature.Upgrade($true);
        $newVersion = $feature.Version;
        Write-Host "      New version:" $newVersion;
        if ($oldVersion -eq $newVersion) {
            Write-Host "  Something went wrong upgrading this feature!" -ForegroundColor Red;
        } else {
            Write-Host "  Upgrade successful." -ForegroundColor Green;
            $count++;
        }
    }
}
""
if ($count -eq 0) {
    Write-Host "No features found that needed upgrading." -ForegroundColor Yellow;
} else {
    Write-Host "Done upgrading" $count "feature(s)." -ForegroundColor Green;
}

Note that there is a wait-loop in there because we cannot start upgrading features right after the solution is upgraded. This is because the solution upgrade happens through a timer task, which might take a while.

We can now put this code in a .ps1 file and have the administrators run it, without requiring any further installations on the production farm or interaction other than starting the script.

I have not really used Power Shell before this, so it might not be optimal, but it seems to work ;) Hope this helps someone! One thing to note is that for some reason, I cannot run this script twice in a row in the same PowerShell window (it will only detect which features to upgrade the first time it is run). I suspect I’m not closing something properly, but I have yet to find out what. If anyone notices the error, please let me know in the comments.

2 thoughts on “Upgrade a SharePoint 2010 solution with features using Power Shell

  1. hi olaf…thanks for your article.
    I have issuse in line “QueryFeatures(“Site”, $true);” always result return null
    I read some article and change to “$webapp = Get-SPWebApplication $webAppUrl;
    $queryFeatureResults=$null;
    $webapp.Sites | ForEach-Object {$queryFeatureResults += $_.QueryFeatures(“Site”,$true)};

    but result the same….
    I don’t know why

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.