Automated deployment of SharePoint solutions is an important part of any SharePoint project you may be involved with. When developing, it is acceptable (and reasonable) to manually deploy your feature when you are making frequent changes. However, once you are ready to deploy your feature to a staging or production environment, you should not be deploying (and activating) your feature manually. In this article, I will show you a script that you can use as a starting point for automating your deployment process, using Powershell. This script is not a fully automatic script, as it is initiated by manually running a batch file, but it serves as a starting point for creating a fully automatic deployment process. I am also including the source files for the script at the end of this article.
Installation and Deployment Script
I am going to begin with describing the script to install and deploy a SharePoint feature solution to a site collection. There are a number of files as part of this script, and I will explain each one, and how they function.
PSFunctions.ps1
This is the main Powershell script, and holds the Powershell commands that do the actual work of installing/deploying the features to a site collection. Please note that there are commands at the top of the script file to load the SharePoint PowerShell snapin when calling any of the methods defined in this script. This snapin is required, and the scripts will not run properly unless you first load this snapin.
There are four methods in this file, they are:
- Install-Solutions
- Install-Solution
- Remove-Solutions
- Remove-Solution
You will notice that the
Install-Solutions and
Remove-Solutions methods call their singular counterpart methods in a
ForEach-Object loop. The idea is that these methods read a configuration XML file (solutions.xml, explained later), and iterate through the nodes of that XML file, calling the appropriate method (
Install-Solution or
Remove-Solution).
function Install-Solutions([string]$configFile)
{
if ([string]::IsNullOrEmpty($configFile)) { return }[xml][/xml]$solutionsConfig = Get-Content $configFileif ($solutionsConfig -eq $null) { return }$solutionsConfig.Solutions.Solution | ForEach-Object {
[string]$path = $_.Path
[bool]$gac = [bool]::Parse($_.GACDeployment)
[bool]$cas = [bool]::Parse($_.CASPolicies)
$webApps = $_.WebApplications.WebApplication
$siteColls = $_.SiteCollections.SiteCollection
Install-Solution $path $gac $cas $webApps $siteColls
}
}
Figure 1: Install-Solutions method in PowerShell
The
Install-Solution method, when called, will deactivate the solution on the site collection it is attempting to install to (if the solution is already present and activated), retract the solution on the site collection (if present and deployed). The method will then delete the solution and add the solution, using the WSP file referenced in the solutions.xml file (passed as a parameter to the method). The method will then deploy the solution to either the farm level, or the site collection(s) listed in the solutions.xml file. The method will pause until the solution is deployed before allowing the script to continue (important if there are multiple features to deploy).
function Install-Solution([string]$path, [bool]$gac, [bool]$cas, [string[]]$webApps = @(), [string[]]$siteColls = @())
{
$spAdminServiceName = "SPAdminV4"[string]$name = Split-Path -Path $path -Leaf[string]$featureName = $name.Replace('.wsp', '*')$solution = Get-SPSolution $name -ErrorAction SilentlyContinueif ($solution -ne $null) {
#Deactivating the solution (scope=site collection ONLY)
Write-Host "Deactivating solution $name..."$siteColls | ForEach-Object {
$FeatureID = Get-SPFeature | where { $_.DisplayName -like $featureName }if($FeatureID -ne $null)
{
#Check whether Feature is activated for the site collection
if (Get-SPFeature -Site $_ | Where {$_.ID -eq $FeatureID.Id})
{
Write-Host "Deactivating $name on $_"
Disable-SPFeature -Identity $featureID -URL $_ -Confirm:$false
}
else
{
Write-Host $FeatureID "is already deactivated at : " $_
}
}
}#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))
}
Stop-Service -Name $spAdminServiceName
Start-SPAdminJob -Verbose
Start-Service -Name $spAdminServiceName
}
Figure 2: Install-Solution method in PowerShell
The
Remove-Solutions and
Remove-Solution methods (see attached source code) are similar to the Install methods, as they retract and remove one or more solutions, but do not install any solutions to a site collection.
InstallFeatures.ps1
This Powershell script is used to call into the PSFunctions.ps1 file, and is called from a batch file. This file calls the
Install-Solutions method from PSFunctions.ps1, passing in the relative path to the solutions.xml file.
. .PSFunctions.ps1Install-Solutions ".solutions.xml"
Figure 3: InstallFeatures.ps1 file in PowerShell
InstallFeatures.bat
This batch file is used to start the install/remove process, as it calls into PowerShell and instructs PowerShell to execute the commands in the InstallFeatures.ps1 file. Please be aware that you will need farm admin privileges when executing this batch file, or you will get security access errors. This batch file will then pause in the command window when the PowerShell script is finished executing.
powershell -Command "& {.InstallFeatures.ps1" -NoExit}
pause
Figure 4: InstallFeatures.bat batch file
Solutions.xml
This XML configuration file is used to instruct the PowerShell script files what solution to install, and what web application in SharePoint it install and deploy it to. The XML file is structured in such a way so that the script files can install and deploy more than one feature in a single execution of the script. There are a number of nodes defined in this file, described below:
- Solutions – Top outer XML element node, this is the parent of the child nodes in the XML file
- Solution– This XML element node defines the solution to be installed/deployed. There can be multiple definitions of this node, depending on how many solutions you need to install/deploy. There are a number of attributes that are defined as part of a Solution node:
- Path – Defines the file path to the WSP file
- CASPolicies – specifies that Code Access Security (CAS) policies can be deployed for the solution
- GACDeployment – Defines whether or not to deploy the solution to the Global Assembly Cache (GAC)
- WebApplications – Parent XML element node
- WebApplication – This XML element node defines the web application that the solution should be deployed to
http://intranet.wingtip.com/
http://intranet.wingtip.com/sites/TestSite1/
http://intranet.wingtip.com/
http://intranet.wingtip.com/sites/TestSite2/
Figure 5: Solutions.xml file
I usually place the solutions.xml file in a subdirectory with all the WSP files, and modify the InstallFeatures.ps1 file to point to this file.
Executing the Script
Once the Powershell files are configured, you are ready to execute the batch files to install and deploy your solutions. To do this, open a command window (
cmd.exe) with administrator privileges. Navigate to the directory that holds the InstallFeatures.bat file and execute this batch file. You will see a number of messages appear as the batch file is executing. Watch for any error messages (in red) while the Powershell script is running, and investigate appropriately. Once the script is done, the batch file will pause until you press any key. Your solution features should now be installed and deployed!
Activation and Deactivation Script
The Powershell script to install and deploy your solution features is a great script for automatically deploying your features, but there is one drawback: You still have to manually activate/deactivate your solution features (via the SharePoint UI). I have noticed that using the install Powershell scripts on existing solution features may cause irregularities or errors with your features, as the scripts will not explicitly deactivate your features before removing them.
In order to resolve these issues, I have updated the Powershell scripts to deactivate the feature before it removes the feature (if it exists), and activate the feature after it has been installed and deployed. This requires modifications to only the PSFunctions.ps1 file, shown in Figures 6 and 7:
Figure 6: Deactivate code in PSFunctions.ps1 PowerShell script
Figure 7: Activate code in PSFunctions.ps1 PowerShell script
Execution of the scripts would be done normally, once these changes are made.
Conclusion
Automating the process of installing and deploying solution features in SharePoint is a powerful and useful tool that can now be added to your utility belt of things for SharePoint. I hope these scripts are useful to you when deploying your solutions.
Have fun deploying!