Thursday, June 6, 2013

Automating SharePoint Deployment – One click deployment for any number of SharePoint solutions



Our SharePoint development team has three week Sprint release scrum process. Each Sprint release we have about 5-10 different solutions need to be deployed. The solutions are might be either global or web application scope. We have automated SharePoint deployment script for each solution to simplify the release process. However, we are seen several following issues that inspires me to future enhance the scripts.

  • Maintainability – Each deployment powershell script need to be modified to add solution names. No centralize script for ALL solution deployments
  • Extensibility – Multiple deployment scripts in each Sprint release and new script need to be created for each new solution
  • Reusability – Each solution script might be different since it could be either global or web application scope
  • Usability – We might need to change each script for each solution based on the scope of the solution

The design we put in place is the one click deployment for any number of SharePoint solutions. This script can be used for each Sprint release, set up new environment,  and SharePoint 2013 upgrade. Here is the typical structure of the PowerShell deployment script and folder structure.

   1. Deploy.bat file – Window batch file that can be clicked to start deployment
   2. Deploy.ps1 – Powershell script that will be called by Deploy.bat to deploy solutions
   3. Config.xml – Configuration file read by Deploy.ps1 for wsp files
   4. Solution-n – Folder that includes the wsp solution. Each solution we separate into different folder




The process is very simple and illustrated in the following diagram.


Let's review the details of the each file.

1. Deply.bat is a window batch file to call powershell script

      cd /d %~dp0

      powershell -noexit -file    ".\Deploy.ps1" "%CD%"

      pause

2. Deploy.ps1 is the key powershell includes many error handling and condition handling. The key command snippet is listed here.

    // Set up log file
    // Read config file and read wsp solution locations and loop through each solution

    // If solution exist - redeploy the solution, otherwise

    // If this is new deployment – add solution
    $status = Add-SPSolution -LiteralPath $solutionInstance.InnerText  

    // If this is webapplication scope and deploy to all webapp
    $status = Install-SPSolution -Identity $solutionInstance.InnerText -AllWebApplications -GACDeployment –force

    // Else if this is webapplication scope and deploy to specific webapp
    $status = Install-SPSolution -Identity $solutionInstance.InnerText -WebApplication $WebAppUrl -GACDeployment –force

    // Else if this is farm scope and deploy to farm
    $status = Install-SPSolution -Identity $solutionInstance.InnerText -GACDeployment -force
 


3. Config.xml will include solution wsp location, the scope of the solution, and actions need to be done. Here is the sample config.

<?xml version="1.0" encoding="UTF-8"?>
 <Setup WebAppUrl="http://sharepointweb">

    <PreActions>
        <PreAction>Enable_All_Webconfig_Editable</Action>              
   </PreActions>  

    <Solutions>
        <Solution WebApplication="False">.\Solution-1\Solution1.wsp</Solution>
        <Solution WebApplication="True" AllWebApps="True">.\Solution-2\Solution2.wsp</Solution>
        ...
        <Solution WebApplication="True" AllWebApps="True">.\Solution-n\Solutionn.wsp</Solution>
    </Solutions>
   
    <PostActions>       

        <PreAction>Make_All_Webconfig_ReadOnly</Action>   
        <PostAction>Some action like active features</Action>                      
        <PostAction>Cleanup_Timer_Job_Cache</Action>    
        <PostAction>IISRESET_4_All_Servers</Action>                     
    </PostActions>   
</Setup>

We also enhanced the script to verify whether solution deploy completed before next wsp deployment using the following code snippet.


      do {

                                $targetSolution = Get-SPSolution | Where-Object {$_.Name -eq  $solutionInstance.InnerText}
                                Sleep -Milliseconds 200
          } while ($targetSolution.Deployed -eq $false)

 
Now we have a true one click deployment script that can be used to deploy any number of solutions with one configuration file to modify. We are using this process in all SharePoint Sprint release and 2013 solution deployment.

We are in the progress to enhance the script to include the following items in the deployment scripts.
  • WCF deployment
  • Workflow deployment
  • Sandbox solution
  • Mass feature activation
  • Invocation of external powershell actions
We will add more functions as we work on SharePoint 2013.






2 comments: