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