In my previous post (see Add custom javascript file to all pages in on-premise Sharepoint site collection without modifying masterpage) I showed how to inject custom javascript file to all pages on all sites in all site collections of specified web application without modifying master page. In this post I will show how to do the same using client object model for Sharepoint Online. For enumerating all site collections in Sharepoint Online we will use technique described in my other post Enumerate all tenant’s site collections in Sharepoint Online via PowerShell. Here is PowerShell which adds custom javascript to all site collections on Sharepoint Online:
1: param(
2: [string]$adminWebAppUrl,
3: [string]$login,
4: [string]$password
5: )
6:
7: $currentDir = Convert-Path(Get-Location)
8: $dllsDir = resolve-path($currentDir + "\..\dlls")
9:
10: [System.Reflection.Assembly]::LoadFile([System.IO.Path]::Combine($dllsDir,
11: "Microsoft.SharePoint.Client.dll"))
12: [System.Reflection.Assembly]::LoadFile([System.IO.Path]::Combine($dllsDir,
13: "Microsoft.SharePoint.Client.Runtime.dll"))
14: [System.Reflection.Assembly]::LoadFile([System.IO.Path]::Combine($dllsDir,
15: "Microsoft.SharePoint.Client.Taxonomy.dll"))
16: [System.Reflection.Assembly]::LoadFile([System.IO.Path]::Combine($dllsDir,
17: "Microsoft.Online.SharePoint.Client.Tenant.dll"))
18:
19: Import-Module ..\spps\spps.psm1
20: Import-Module ..\spps\spps.subsites.psm1
21:
22: if (-not $adminWebAppUrl)
23: {
24: Write-Host "Specify admin web app url in adminWebAppUrl parameter" -foregroundcolor red
25: return
26: }
27:
28: if (-not $login)
29: {
30: Write-Host "Specify user name in login parameter" -foregroundcolor red
31: return
32: }
33:
34: if (-not $password)
35: {
36: Write-Host "Specify user password in password parameter" -foregroundcolor red
37: return
38: }
39:
40: function Upload-Script($ctx, $web)
41: {
42: Write-Host "Upload script to Site Assets" -foregroundColor Green
43: $ctx.Load($web.Lists)
44: $ctx.ExecuteQuery()
45:
46: $assetsLib = $null
47: foreach ($l in $web.Lists)
48: {
49: if ($l.Title -eq "Site Assets")
50: {
51: $assetsLib = $l
52: break
53: }
54: }
55:
56: if (-not $assetsLib)
57: {
58: Write-Host "Sites Assets doclib not found. Script won't be uploaded" -foregroundcolor red
59: return
60: }
61:
62: $fileName = "foo.js"
63: $filePath = [System.IO.Path]::Combine($currentDir, $fileName)
64: if (-not [System.IO.File]::Exists($filePath))
65: {
66: Write-Host "File $filePath doesn't exist. It won't be uploaded" -foregroundcolor red
67: return
68: }
69:
70: $newFile = New-Object "Microsoft.SharePoint.Client.FileCreationInformation"
71: $newFile.Content = [System.IO.File]::ReadAllBytes($filePath)
72: $newFile.Url = $fileName
73: $newFile.Overwrite = $true
74: $uploadFile = $assetsLib.RootFolder.Files.Add($newFile)
75:
76: $ctx.Load($uploadFile)
77: $ctx.ExecuteQuery()
78: }
79:
80: function Add-Link($ctx, $web, $actionUrl, $sequence)
81: {
82: Write-Host "Add custom action link" -foregroundColor Green
83: $existingActions = $web.UserCustomActions
84: $ctx.Load($existingActions)
85: $ctx.ExecuteQuery()
86:
87: $exists = $false
88: foreach($ac in $existingActions)
89: {
90: if ($ac.ScriptSrc.ToLower() -eq $actionUrl)
91: {
92: $exists = $true
93: break
94: }
95: }
96:
97: if ($exists)
98: {
99: Write-Host "Custom action is already added" -foregroundcolor Yellow
100: return
101: }
102:
103: $gaScript = $existingActions.Add()
104: $gaScript.Location = "ScriptLink"
105: $gaScript.ScriptSrc = $actionUrl
106: $gaScript.Sequence = $sequence
107: $gaScript.Update()
108:
109: $ctx.ExecuteQuery()
110: }
111:
112: function Add-Custom-Action($url)
113: {
114: Write-Host "Adding custom action to $url" -foregroundColor Green
115: $clientContext = New-Object Microsoft.SharePoint.Client.ClientContext($url)
116: $clientContext.RequestTimeOut = 1000 * 60 * 10;
117: $clientContext.AuthenticationMode =
118: [Microsoft.SharePoint.Client.ClientAuthenticationMode]::Default
119: $securePassword = ConvertTo-SecureString $password -AsPlainText -Force
120: $credentials =
121: New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($username,
122: $securePassword)
123: $clientContext.Credentials = $credentials
124: $web = $clientContext.Web
125: $site = $clientContext.Site
126: $clientContext.Load($web)
127: $clientContext.Load($site)
128: $clientContext.ExecuteQuery()
129:
130: Upload-Script $clientContext $clientContext.Web
131: Add-Link $clientContext $clientContext.Web "~sitecollection/SiteAssets/foo.js" 10001
132: }
133:
134: Start-Transcript -Path "output.log" -Append -Force -Confirm:$false
135:
136: # initialize client context
137: $clientContext = New-Object Microsoft.SharePoint.Client.ClientContext($adminWebAppUrl)
138: $clientContext.RequestTimeOut = 1000 * 60 * 10;
139: $clientContext.AuthenticationMode =
140: [Microsoft.SharePoint.Client.ClientAuthenticationMode]::Default
141: $securePassword = ConvertTo-SecureString $password -AsPlainText -Force
142: $credentials =
143: New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($username,
144: $securePassword)
145: $clientContext.Credentials = $credentials
146: $web = $clientContext.Web
147: $site = $clientContext.Site
148: $clientContext.Load($web)
149: $clientContext.Load($site)
150: $clientContext.ExecuteQuery()
151:
152: $tenant = New-Object "Microsoft.Online.SharePoint.TenantAdministration.Tenant" -ArgumentList $clientContext
153: $props = $tenant.GetSiteProperties(0, $true)
154: $clientContext.Load($props)
155: $clientContext.ExecuteQuery()
156:
157: foreach($sp in $props)
158: {
159: Add-Custom-Action $sp.Url
160: }
161:
162: Stop-Transcript
In this script we at first enumerate all tenant site collections (lines 136-160). For each site collection we at first upload custom javascript file to Site Assets doclib (lines 40-78) and then add custom action with script reference on added javascript file (lines 80-110). As result our custom javascript file will be added to all pages in all site collections in Sharepoint Online web app.
No comments:
Post a Comment