Thursday, 7 May 2015

Powershell:Add and deploy multiple wsp

Introduction

In SharePoint 2010 if we want to deploy the wsp; we will just right click the project and select deploy. SharePoint will take care of deploying with the given settings.
But,we can’t deploy the package in the same way in other environments like UAT, PreProduction or Production (unless you are a super user having permission in all environments and you have source code of the package)
In this article I will provide a generic method where you just provide the path of the folder where wsp is located (more than one wsp is also supported) and the function will take care to install wsp. It will be very useful while deploying in any environments

Deploy WSP

Following is the example how to use the generic function Deploy-SPSolution
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Remove-PSSnapin Microsoft.SharePoint.PowerShell -erroraction SilentlyContinue
Add-PSSnapin Microsoft.SharePoint.PowerShell -erroraction SilentlyContinue
 
function WaitForInsallation([string] $Name)
{
        Write-Host -NoNewline "Waiting for deployment job to complete" $Name "."
        $wspSol = get-SpSolution $Name
        while($wspSol.JobExists)
        {
            sleep 2
            Write-Host -NoNewline "."
            $wspSol = get-SpSolution $Name
        }
        Write-Host "job ended" -ForegroundColor green
}
 
Function Deploy-SPSolution ($WspFolderPath)
{
    $wspFiles = get-childitem $WspFolderPath | where {$_.Name -like "*.wsp"}
 
    ForEach($file in $wspFiles)
    {
        $wsp = Get-SPSolution | Where{$_.Name -eq $file.Name}
        if($wsp -eq $null)
        {
            write-host "Adding solution"
            Add-SPSolution -LiteralPath ($WspFolderPath + "\" + $file.Name)
        }
        else
        {
            write-host "solution already exists"
 
            if($wsp.Deployed -eq $true)
            {
                write-host "solution is deployed already, updating the solution"
                Update-SPSolution -identity $wsp.SolutionId -LiteralPath ($WspFolderPath + "\" + $file.Name) -GACDeployment
            }
             else
            {
               write-host "Removing solution"
               Remove-SPSolution -identity $wsp.SolutionId -confirm:$false
 
                write-host "Adding solution"
               Add-SPSolution -LiteralPath ($WspFolderPath + "\" + $file.Name)
            }
            WaitForInsallation -Name $wsp.Name
        }
 
        $wsp = Get-SPSolution | Where {$_.Name -eq $file.Name}
        if($wsp -ne $null)
        {
            write-host "installing solution"
            Install-SPSolution -identity $wsp.SolutionId -GACDeployment -force
        }
        WaitForInsallation -Name $wsp.Name
 
    }
    write-host "Done"
}
try
{
        Deploy-SPSolution "C:\Custom\Projects\AdiCodes\WspPackages"
}
catch
{
    write-host $_.exception
 
}

Description

Usage:
Deploy-SPSolution “C:\Custom\Projects\AdiCodes\WspPackages”
“C:\Custom\Projects\AdiCodes\WspPackages” is the folder path where wsp packages are resided.
Function will read all the wsp’s inside the specified folder.
Deploy-SPSolution will be using another function WaitForInsallation inside it.
This function is necessary because, we cannot install application before previous job is completed. If this function is not there we will get errors similar like

Install-SPSolution : A deployment or retraction is already under way for the solution “xxx.wsp”, and only one deployment or retraction at a time is supported.

If you are getting the error that means, you are trying to deploy wsp where timer job is already busy deploying with previous wsp.
You can try checking timer job status from central admin. If timer job is still running you cannot deploy until its job is done.
If at any case you are stuck and always getting this error, then you need to restart timer job in web front end server and also in app server.

Remarks

The above function considers the wsp’s to be deployed in GAC. If the wsp is targeted to a specific webapplication with any CASPolicies rather than GAC, remove the code from line 49 to 55 and place the following code in the above function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$url="http://AdisGroup/MySite"
write-host "url address" $url
$webApp=Get-SPWebApplication -identity $url
$wsp = Get-SPSolution | Where {$_.Name -eq $file.Name}
$DeployedWebapps=$sol.DeployedWebApplications | where {$_.Url -like $url }
if($DeployedWebapps -eq $null)
{
    Write-host "Deploy Solution" $wsp.Name
    #Change the following line of code according to the targetted settings of wsp
    $wsp |Install-SPSolution -WebApplication $webApp.Url -CASPolicies -GACDeployment -Force
}
else
{
    Write-host "Update Solution" $wsp.Name
    $wsp |Update-SPSolution  -LiteralPath $wsp.FullName -Force
}
WaitForInsallation -Name $wsp.Name

Conclusion

With the above method it should be quicker to deploy any wsp in any environment without dependency on visual studio.
I prefer using logging and config mechanism to include along with code to make it more generic.
Refer best way to use config file and how to log information in powershell if you are not aware of.
If you are stuck up or if you face any problems while executing the above script, drop a comment. Happy coding :)

You may also like


No comments:

Post a Comment