dinsdag 30 november 2010

SharePoint 2010 Deployment script using Powershell

For a project I was working on last month, I needed a way to deploy SharePoint 2010 solutions in a controlled manner.
Thanks to Gary Lapointe I was quickly up to speed to create my first Powershell Script. The script he provided in his post makes it possible to deploy solutions using a xml configuration file. But I needed a script that activates the features as well, so I extended Gary's script.

solutions.xml
<Solutions>
<Solution Path="[[Solution1.wsp]]" CASPolicies="false" GACDeployment="true">
<WebApplications>
<WebApplication Url="[[URL]]:8080">
<Feature Name="1116af9b-e3b5-498e-9706-1b67b7b60c43" Url="[[URL]]" />
<Feature Name="2220d8aa-2d25-47bb-8d44-29a45caaa4ce" Url="[[URL]]" />
<Feature Name="3330364b-e879-4fee-b103-3c3dd10c0a1c" Url="[[URL]]" />
<Feature Name="444a36e0-d249-469a-ba46-4ca7baa10ea6" Url="[[URL]]" />
</WebApplication>
</WebApplications>
</Solution>
<Solution Path="[[Solution2.wsp]]" CASPolicies="false" GACDeployment="true">
<WebApplications>
<WebApplication Url="[[URL]]">
<Feature Name="Feature1" Url="[[URL]]" />
</WebApplication>
</WebApplications>
</Solution>
</Solutions>


Deplopy.ps1
$solutionfile = "solutions.xml"

if ( (Get-PSSnapin -Name Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue) -eq $null )
{
Add-PSSnapin Microsoft.SharePoint.PowerShell
}

function Install-Solutions([string]$configFile)
{
if ([string]::IsNullOrEmpty($configFile)) { return }

[xml]$solutionsConfig = Get-Content $configFile
if ($solutionsConfig -eq $null) { return }

$solutionsConfig.Solutions.Solution | ForEach-Object {

$_.WebApplications.WebApplication | ForEach-Object {
Write-Host $_.Url
$_.Feature | ForEach-Object {
Write-Host $_.Name
[string]$name = $_.Name
[string]$url = $_.Url
Write-Host Deactivate-Feature $name $url
Deactivate-Feature $name $url
}
}

[string]$path = $_.Path
[bool]$gac = [bool]::Parse($_.GACDeployment)
[bool]$cas = [bool]::Parse($_.CASPolicies)
$webApps = $_.WebApplications.WebApplication
Write-Host Install-Solution $path $gac $cas $webApps.Url
Install-Solution $path $gac $cas $webApps.Url

$_.WebApplications.WebApplication | ForEach-Object {
$_.Feature | ForEach-Object {
[string]$name = $_.Name
[string]$url = $_.Url
Activate-Feature $name $url
}
}
}
}

function Deactivate-Feature([string]$featurename, [string]$url)
{
#Check for Sitecollection-scoped feature
$feature = Get-SPFeature $featurename -Site $url -ErrorAction SilentlyContinue
if ($feature -eq $null) {
#Check for Web-scoped feature
$feature = Get-SPFeature $featurename -Web $url -ErrorAction SilentlyContinue
}

if ($feature -ne $null) {
Write-Host Disable-SPFeature -Identity $featurename -Url $url
Disable-SPFeature -Identity $featurename -Url $url -Confirm:$false
}

}

function Activate-Feature([string]$featurename, [string]$url)
{
$feature = Get-SPFeature $featurename -ErrorAction SilentlyContinue
if ($feature -ne $null) {
Write-Host Enable-SPFeature -Identity $featurename -Url $url
Enable-SPFeature -Identity $featurename -Url $url
}
}

function Install-Solution([string]$path, [bool]$gac, [bool]$cas, [string[]]$webApps = @())
{
$spAdminServiceName = "SPAdminV4"

[string]$name = Split-Path -Path $path -Leaf
$solution = Get-SPSolution $name -ErrorAction SilentlyContinue

if ($solution -ne $null) {
#Retract the solution
if ($solution.Deployed) {
Write-Host "Retracting solution $name..."
if ($solution.ContainsWebApplicationResource) {
$solution | Uninstall-SPSolution -AllWebApplications -Confirm:$false
} else {
$solution | Uninstall-SPSolution -Confirm:$false
}
Stop-Service -Name $spAdminServiceName
Start-SPAdminJob -Verbose
Start-Service -Name $spAdminServiceName

#Block until we're sure the solution is no longer deployed.
do { Start-Sleep 2 } while ((Get-SPSolution $name).Deployed)
}

#Delete the solution
Write-Host "Removing solution $name..."
Get-SPSolution $name | Remove-SPSolution -Confirm:$false
}

#Add the solution
Write-Host "Adding solution $name..."
$solution = Add-SPSolution $path

#Deploy the solution
if (!$solution.ContainsWebApplicationResource) {
Write-Host "Deploying solution $name to the Farm..."
$solution | Install-SPSolution -GACDeployment:$gac -CASPolicies:$cas -Confirm:$false
} else {
if ($webApps -eq $null -or $webApps.Length -eq 0) {
Write-Warning "The solution $name contains web application resources but no web applications were specified to deploy to."
return
}
$webApps | ForEach-Object {
Write-Host "Deploying solution $name to $_..."
$solution | Install-SPSolution -GACDeployment:$gac -CASPolicies:$cas -WebApplication $_ -Confirm:$false
}
}
Stop-Service -Name $spAdminServiceName
Start-SPAdminJob -Verbose
Start-Service -Name $spAdminServiceName

#Block until we're sure the solution is deployed.
do { Start-Sleep 2 } while (!((Get-SPSolution $name).Deployed))
}

function Get-ScriptDirectory
{
$Invocation = (Get-Variable MyInvocation -Scope 1).Value
Split-Path $Invocation.MyCommand.Path
}

Install-Solutions($solutionfile);

2 opmerkingen:

  1. You say you wanted to activate, does this just activate at the WebApp scope. it doesn't appear to be at the site collection or web scopes?

    BeantwoordenVerwijderen
  2. Although it seems that way, it's not only for WebApp scoped features. It just calls Enable-SPFeature with a name and url. This cmdlet automatically determines the scope of the feature.
    I actually used this script for Web and Site scoped features. Haven't tried using this script for WebApp features. I guess it should work for WebApp scoped features.

    BeantwoordenVerwijderen