Most of Sharepoint developers often deployed farm solutions to Sharepoint web application using Add-SPSolution and Install-SPSolution PowerShell cmdlets. In order to deploy sandbox solutions to on-premise Sharepoint sites we can use appropriate sandbox versions of mentioned cmdlets: Add-SPUserSolution and Install-SPUserSolution. Unfortunately these cmdlets work only on-premise. But how to upload sandbox solution to Sharepoint Online site?
In order to do it we may use Sharepoint Online helper open source project which is hosted on Codeplex. It makes changes in solutions gallery by using client object model. For authentication you have to provide your user name and password for Sharepoint Online site. They will be used for getting authentication cookies which then will be used for making authenticated requests.
At the moment of writing this post it had the following methods for managing sandbox solutions in Sharepoint Online:
- Upload solution
- Activate solution
- Deactivate solution
Unfortunately for complete set of methods it didn’t contain Delete solution method. So first of all we need to add this method to the library. Code is hosted on codeplex with compiled library, so it is quite easy to do:
1: public static void DeleteSolution(String siteCollectionUrl,
2: CookieContainer cookies, String filePath)
3: {
4: siteCollectionUrl = siteCollectionUrl.TrimEnd('/');
5: var fileInfo = new FileInfo(filePath);
6: var ctx = Authenticator.GetClientContext(siteCollectionUrl, cookies);
7:
8: var fileUrl = String.Format("{0}/_catalogs/solutions/{1}",
9: siteCollectionUrl, fileInfo.Name);
10: var fileUri = new Uri(fileUrl);
11:
12: Microsoft.SharePoint.Client.File file =
13: ctx.Web.GetFileByServerRelativeUrl(fileUri.AbsolutePath);
14: ctx.Load(file);
15: file.DeleteObject();
16: ctx.ExecuteQuery();
17: }
I also provided patch with this method on project’s site. After that we have all methods we need for managing sandbox solutions on Sharepoint Online site.
Next step is to write PowerShell script for uploading, activating, deactivating and deleting solutions remotely:
1: param(
2: [switch]$uploadSolution,
3: [switch]$deactivateSolution,
4: [switch]$activateSolution,
5: [switch]$deleteSolution,
6: [switch]$updateSolution
7: )
8:
9: . ./Params.ps1
10:
11: [System.Reflection.Assembly]::LoadFile([System.IO.Path]
12: ::Combine($externalDllsDirectory, "Microsoft.SharePoint.Client.dll"))
13: [System.Reflection.Assembly]::LoadFile([System.IO.Path]
14: ::Combine($externalDllsDirectory, "Microsoft.SharePoint.Client.Runtime.dll"))
15: [System.Reflection.Assembly]::LoadFile([System.IO.Path]
16: ::Combine($externalDllsDirectory, "SharePointOnline.Helper.dll"))
17:
18: function Get-Auth-Cookies()
19: {
20: Write-Host "Get authentication cookies from O365-foregroundcolor Green
21: $cookies = [SharePointOnline.Helper.Authenticator]
22: ::GetAuthenticatedCookies($siteCollUrl, $login, $password)
23: return $cookies
24: }
25:
26:
27: function Upload-Solution-Impl($cookies)
28: {
29: Write-Host "Upload solution $solutionName to $siteCollUrl"
30: -foregroundcolor Green
31: [SharePointOnline.Helper.SandboxSolutions]
32: ::UploadSolution($siteCollUrl, $cookies, $solutionFullPath)
33: Write-Host "Solution was successfully uploaded" -foregroundcolor Green
34: }
35:
36: function Upload-Solution()
37: {
38: $cookies = Get-Auth-Cookies
39: Upload-Solution-Impl $cookies
40: }
41:
42: function Activate-Solution-Impl($cookies)
43: {
44: Write-Host "Activate solution $solutionName on $siteCollUrl"
45: -foregroundcolor Green
46: [SharePointOnline.Helper.SandboxSolutions]
47: ::ActivateSolution($siteCollUrl, $cookies, $solutionName)
48: Write-Host "Solution was successfully activated" -foregroundcolor Green
49: }
50:
51: function Activate-Solution()
52: {
53: $cookies = Get-Auth-Cookies
54: Activate-Solution-Impl $cookies
55: }
56:
57: function Deactivate-Solution-Impl($cookies)
58: {
59: Write-Host "Deactivate solution $solutionName on $siteCollUrl"
60: -foregroundcolor Green
61: [SharePointOnline.Helper.SandboxSolutions]
62: ::DeactivateSolution($siteCollUrl, $cookies, $solutionName)
63: Write-Host "Solution was successfully deactivated" -foregroundcolor Green
64: }
65:
66: function Deactivate-Solution()
67: {
68: $cookies = Get-Auth-Cookies
69: Deactivate-Solution-Impl $cookies
70: }
71:
72: function Delete-Solution-Impl($cookies)
73: {
74: Write-Host "Delete solution $solutionName from $siteCollUrl"
75: -foregroundcolor Green
76: [SharePointOnline.Helper.SandboxSolutions]
77: ::DeleteSolution($siteCollUrl, $cookies, $solutionName)
78: Write-Host "Solution was successfully deleted" -foregroundcolor Green
79: }
80:
81: function Delete-Solution()
82: {
83: $cookies = Get-Auth-Cookies
84: Delete-Solution-Impl $cookies
85: }
86:
87: function Update-Solution()
88: {
89: $cookies = Get-Auth-Cookies
90: Deactivate-Solution-Impl $cookies
91: Delete-Solution-Impl $cookies
92: Upload-Solution-Impl $cookies
93: Activate-Solution-Impl $cookies
94: }
95:
96: # solutions management
97: if ($uploadSolution)
98: {
99: Upload-Solution
100: }
101:
102: if ($activateSolution)
103: {
104: Activate-Solution
105: }
106:
107: if ($deactivateSolution)
108: {
109: Deactivate-Solution
110: }
111:
112: if ($deleteSolution)
113: {
114: Delete-Solution
115: }
116:
117: if ($updateSolution)
118: {
119: Update-Solution
120: }
In Params.ps1 script we define path to solution on local file system, site url, user name and password for Sharepoint Online:
1: # Configure environment specific variables here.
2: # Use absolute paths if needed.
3: $currentPath = Convert-Path(Get-Location)
4: $externalDllsDirectory = resolve-path($currentPath + "\ExternalDll\")
5: $packageDirectory = resolve-path($currentPath + "\Packages\")
6: $solutionName = "Test.wsp"
7: $solutionFullPath = [System.IO.Path]::Combine($packageDirectory, $solutionName)
8:
9: $siteCollUrl = "http://example.com"
10: $login = "login"
11: $password = "password"
After that in order to update our solution (deactivate, delete, upload and activate) we may use the following command:
1: .\install.ps1 -updateSolution
Also we may execute mentioned tasks separately if needed. I hope that this article will be useful and will help you in your work.