Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / productivity / SharePoint

Deploy solution wsp to SharePoint

0.00/5 (No votes)
28 Sep 2015CPOL 6.5K  
The Microsoft technet article Automated Farm level Solution Deployment and Retraction, gives a very good example of deploying SharePoint wsp solutions using PowerShell.

The Microsoft technet article Automated Farm level Solution Deployment and Retraction, gives a very good example of deploying SharePoint wsp solutions using PowerShell. However, I felt that it would be better to wait for the timer job to complete instead of using sleep command as mentioned in SharePoint 2010: PowerShell to Wait for WSP Solution Deployment Timer Job to Complete

Also, I thought it would be better if we added a configuration xml instead of providing input parameters.

Please feel free to let me know if this script can be enhanced by leaving a comment

We can have a configuration file which contains information such as web application url, site collection and web specific information such as features to be activated. It can have any number of Site and Web sections to handle multiple site collections and webs.

Configuration Config.xml:

<WebApp>
  <WebAppUrl>http://server/webapp</WebAppUrl>
  <Site>
    <SiteUrl>http://server/sites/site1</SiteUrl>
    <Features>
       <Feature>PublishingSite</Feature>
    </Features>
  </Site>
  <Web>
    <WebUrl>http://server/sites/site1</WebUrl>
    <Features>
      <Feature>PublishingWeb</Feature>
    </Features>
  </Web>
</WebApp>

Ensure that the wsps are kept in a subfolder called WSP inside the folder where the script is saved.

So, here is the enhanced script

Powershell Script

$snapin = Get-PSSnapin | Where-Object {$_.Name -eq 'Microsoft.SharePoint.Powershell'} 
if ($snapin -eq $null)  
{ 
    Write-Host "Loading SharePoint Powershell Snapin" 
    Add-PSSnapin "Microsoft.SharePoint.Powershell" 
}
#get the configuration info
$config = 1(Get-Content "Config.xml");

$wspFolderPath = "WSP";
[int]$sleepTime = 4;
$AdminServiceName = "SPAdminV4";
$TimerServiceName = "SPTimerV4";
$url = $config.WebApp.WebAppUrl;

#Start the Admin service if it is not started
if ($(Get-Service $AdminServiceName).Status -eq "Stopped")   
{   
    Start-Service $AdminServiceName   
    Write-Host "Started the SharePoint 2013 Admin Service"
}   

#Start the Timer service if it is not started
if ($(Get-Service $TimerServiceName).Status -eq "Stopped")
{   
    Start-Service $TimerServiceName      
    Write-Host   "Started the SharePoint Timer Job" 
}

function DeactivateSiteFeatures($siteCol)
{
    $siteUrl = $siteCol.SiteUrl
    $Site = Get-SPSite -Identity $siteUrl
    foreach ($featureName in $siteCol.Features.Feature)
    {
        $EnabledSiteFeatures = Get-SPFeature -site $siteUrl
        foreach($enabledFeature in $EnabledSiteFeatures)
        {
		    #Check if feature is already activated. Deactivate if already activated.
		    if($featureName -eq $enabledFeature.DisplayName)
		    {
			    Write-Host "Feature $featureName Activated" -foregroundcolor Green
			    Write-Host "- Deactivating Feature" -foregroundcolor Yellow
				    Start-Sleep 3  
			    Disable-SPFeature -Identity $featureName -url $SiteUrl -confirm:$false
			    Write-Host " -- Feature deactivated successfully"  -foregroundcolor Green
		    }
        }   
    }
    $Site.Dispose() 
}

function ActivateSiteFeatures($siteCol)
{
    $siteUrl = $siteCol.SiteUrl
    $Site = Get-SPSite -Identity $siteUrl
    foreach ($featureName in $siteCol.Features.Feature)
    {
        Write-Host "Activating $featureName feature"  -foregroundcolor Yellow
        Enable-SPFeature -identity $featureName -Url $SiteUrl  -Confirm:$false  
        Start-Sleep 3
        Write-Host " -- Feature activated successfully"  -foregroundcolor Green    
    }
    $Site.Dispose() 
}

function DeactivateWebFeatures($PubWeb)
{
    Write-Host "Deactivating Web features"
    #Web
    $WebUrl = $PubWeb.WebUrl

    foreach ($featureName in $PubWeb.Features.Feature)
    {
        Write-Host "              "
		
        $EnabledWebFeatures = Get-SPFeature -Web $WebUrl

        foreach($enabledFeature in $EnabledWebFeatures)
        {
		    #Check if feature is activated. Deactivate if activated.
			if($featureName -eq $enabledFeature.DisplayName)
		    {
			    Write-Host "Feature $featureName already Activated" -foregroundcolor Green
			    Write-Host "- Deactivating Feature" -foregroundcolor Yellow
				    Start-Sleep 3  
			    Disable-SPFeature -Identity $featureName -url $WebUrl -confirm:$false
			    Write-Host " -- Feature deactivated successfully"  -foregroundcolor Green
		    }
        }
    }
}

function ActivateWebFeatures($PubWeb)
{
    Write-Host "Activating Web features"
    #Web
    $WebUrl = $PubWeb.WebUrl

    foreach ($featureName in $PubWeb.Features.Feature)
    {
        Write-Host "Activating $featureName feature"  -foregroundcolor Yellow
        Enable-SPFeature -identity $featureName -Url $WebUrl -Confirm:$false  
        Start-Sleep 3
        Write-Host " -- Feature activated successfully"  -foregroundcolor Green    
    }

}
function WaitForSPSolutionJobToComplete($solution)
{
    if ($solution)
    {
        $solutionName = $solution.Name;
        if ($solution.JobExists)
        {
            Write-Host -NoNewLine "Waiting for timer job to complete for solution '$solutionName'."
        }
         
        # Check if there is a timer job still associated with this solution and wait until it has finished
        while ($solution.JobExists)
        {
            $jobStatus = $solution.JobStatus
             
            # If the timer job succeeded then proceed
            if ($jobStatus -eq [Microsoft.SharePoint.Administration.SPRunningJobStatus]::Succeeded)
            {
                Write-Host "Solution '$solutionName' timer job suceeded"
                return $true
            }
             
            # If the timer job failed or was aborted then fail
            if ($jobStatus -eq [Microsoft.SharePoint.Administration.SPRunningJobStatus]::Aborted -or
                $jobStatus -eq [Microsoft.SharePoint.Administration.SPRunningJobStatus]::Failed)
            {
                Write-Host "Solution '$solutionName' has timer job status '$jobStatus'."
                return $false
            }
             
            # Otherwise wait for the timer job to finish
            Write-Host -NoNewLine "."
            Sleep 1
        }
         
        # Write a new line to the end of the '.....'
        Write-Host
    }
     
    return $true
}

#deactivate site collection features
foreach ($siteCollection in $config.WebApp.Site)
{
    DeactivateSiteFeatures($siteCollection)
}

#deactivate web features
foreach ($web in $config.WebApp.Web)
{
    DeactivateWebFeatures($web)
}

#WSP Solution
foreach($filename in Get-ChildItem $wspFolderPath)
{
  Write-Host " "
  $SolutionPackageName = $filename.name
  $Solution = Get-SPSolution | ? {($_.Name -eq $SolutionPackageName) -and ($_.Deployed -eq $true)}   
  if ($Solution -ne $null)   
   {   
      Write-Host "Solution already Deployed. Rectracting solution: $SolutionPackageName"  -foregroundcolor Red 
      if($Solution.ContainsWebApplicationResource)   
       {   
            Uninstall-SPSolution $SolutionPackageName -WebApplication $url -Confirm:$false   
       }   
       else   
       {   
            Uninstall-SPSolution $SolutionPackageName -Confirm:$false   
       } 

       # Calling Function to wait for timer job to compelete
       WaitForSPSolutionJobToComplete($Solution)
                 
       Write-Host "-Rectracting $SolutionPackageName solution Done."  -foregroundcolor Green
 
      if ($(Get-SPSolution | ? {$_.Name -eq $SolutionPackageName}).Deployed -eq $false)   
      {   
        Write-Host "Removing solution: $SolutionPackageName"   -foregroundcolor Red
        Remove-SPSolution $SolutionPackageName -Confirm:$false 
        Start-Sleep -Seconds $sleepTime
        Write-Host " - Removing $SolutionPackageName solution Done."  -foregroundcolor Green
      }       
   }  

   Write-Host "-Adding solution: $SolutionPackageName"    -foregroundcolor Green
    $SolutionPath = $PSScriptRoot + "\" +$wspFolderPath +"\"+ $SolutionPackageName 
    Add-SPSolution $SolutionPath | Out-Null
    Start-Sleep -Seconds $sleepTime   
   Write-Host " - Adding $SolutionPackageName Solution Done."  -foregroundcolor Green


   Write-Host "-Deploying solution: $SolutionPackageName"    -foregroundcolor Green
    $Solution = Get-SPSolution | ? {($_.Name -eq $SolutionPackageName) -and ($_.Deployed -eq $false)}   
    if(($Solution -ne $null) -and ($Solution.ContainsWebApplicationResource))   
    {   
        Install-SPSolution $SolutionPackageName -WebApplication $url -GACDeployment -Confirm:$false   
    }   
    else   
    {   
        Install-SPSolution $SolutionPackageName -GACDeployment -Confirm:$false   
    }      
      
    # Calling Function to wait for timer job to compelete
    WaitForSPSolutionJobToComplete($Solution)
    
    Write-Host
    Write-Host " - Deploying $SolutionPackageName solution Done."  -foregroundcolor Green
}

#loop all the site collections
foreach ($siteCollection in $config.WebApp.Site)
{
    ActivateSiteFeatures($siteCollection)
}

#loop all the webs
foreach ($web in $config.WebApp.Web)
{
    ActivateWebFeatures($web)
}

Please let me know your thoughts.

The post Deploy solution wsp to SharePoint appeared first on SharePoint Guide.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)