How to manage your O365 sites with PowerShell and CSOM?
This post explains how to manage your SharePoint Online environment and manipulate SPO objects. In other words, this post describes how to manage SharePoint sites, SharePoint lists using Powershell and CSOM (Client Side Object Model).
1. Prerequisites
In order to use CSOM within your PowerShell scripts, you first need to download the "Office Developer Tools for Visual Studio 2013". This package contains the client Dlls components for SharePoint Online. You can download the office Developer tools on this link.
You can find more details regarding the Office Developer Tools for Visual Studio in the following articles:
- Now Available: Office Developer Tools for Visual Studio 2012 https://blogs.msdn.com/b/somasegar/archive/2013/03/04/now-available-office-developer-tools-for-visual-studio-2012.aspx
- What's New in Office Developer Tools for Visual Studio 2013 – March 2014 Update https://msdn.microsoft.com/library/dn610877.aspx
Note: the examples of this post use the office developer tools of March 2014.
In this post, I' am using a PowerShell version 4.0 provided with Windows 8.1, however the scripts should also work since PowerShell 2.0 (at least).
2. Walkthrough
a. Loading Clients Assemblies
In order to manipulate SharePoint Online objects in our PowerShell script, we first need to load the Clients DLL installed with the Office Developer tools on our local machine.
We will load two client DLLs with the two following lines:
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime")
Note: "Add-Type" cmdlet is an alternative to Loadwithpartialname. LoadWithPartialName is actually deprecated (link).
b. Create Client Context and Authenticate to SPO
Now that the client DLLs have been loaded with the previous lines, we can access the SP client objects model. However in order to manipulate SharePoint objects and run operations, we need a new client context.
To create the context, we first have to provide the site collection URL:
$weburl= 'https://tenant.sharepoint.com/sites/team'
$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($webUrl)
Then we should provide the site collection administrator credentials to the context object to authenticate against on the site:
$username = 'user@tenant.onmicrosoft.com'
$password = Read-Host -Prompt "Password for $username" –AsSecureString
$ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($username, $password)
Note: if the credentials or the WebUrl are wrong, you will face an error when executing the above command.
c. Query Objects through Context
Now that we are authenticated to a SPO Site and that we have a context object, we can access objects by loading them in the current context.
The following query will retrieve the site (SPWeb) in the $ctx:
$web = $ctx.Web
$ctx.Load($web);
$ctx.ExecuteQuery();
$web.Title # will print the name of the site
Note: we could also retrieve the site collection (SPSite), $site = $ctx.Site
Now, that we have the site (SPWeb), we can also query objects like lists (SPList) and their basic properties:
$listname = "Documents"
$list = $context.Web.Lists.GetByTitle($listname);
$ctx.Load($list);
$ctx.ExecuteQuery();
$list.ItemCount # will print the number of documents and folders
3. Example Script
With the following PowerShell script, we will upload a local Temp.txt file to a SharePoint document library.
This script is provided on an "as is" basis without warranties of any kind, whether express or implied. The entire risk as to the quality and performance of the code is with the end user.
$loadInfo1 = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client") $loadInfo2 = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime")
$weburl= Read-Host -Prompt "Please type or paste the site url you want to connect to (ex: https://tenant.sharepoint.com/sites/TeamSite)" $username = Read-Host -Prompt "Enter or paste the site collection administrators user name" $password = Read-Host -Prompt "Password for $username" -AsSecureString $listTitle= Read-Host -Prompt "Please type the Documents library TITLE in which you updload the demo text file(ex: Documents)" #$webUrl = 'https://contoso.sharepoint.com/sites/dev/' #$username = 'administrator@contoso.onmicrosoft.com' #$password = ConvertTo-SecureString 'passwod' -AsPlainText -Force #$ListTitle= "Documents" try { #Creating the SharePoint Context with SP Site Url and the Site Collection admin credential. Write-Output "Connecting to $weburl ..."; $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($webUrl) $ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($username, $password) } catch { Write-output "... Couldn't connect. Please check your credential or the provided Url: $weburl." ; break } #Retrieving the Root Web Write-Output "`nRetrieving Web ..." try { $web = $ctx.Web $ctx.Load($web); $ctx.ExecuteQuery(); } catch{ Write-output 'Unable to get the $web site.'; break } write-output "Web title : $($web.Title)"; write-output "Web Template : $($web.WebTemplate)"; #Retrieving the "Documents" list. Write-Output "`nRetrieving Documents document library..." try { $list = $ctx.Web.Lists.GetByTitle("$ListTitle"); $ctx.Load($list); $ctx.ExecuteQuery(); } catch { Write-Output "Unable to get Documents library. Please check the $listTitle document library exists..." ; break; } Write-Output "List contains: $($list.ItemCount) items." try { #Retrieving the root folder and the Sub folders. Write-Output "`nRetrieving Root Folder of list..." $ctx.Load($list.RootFolder); $ctx.ExecuteQuery(); $folder = $list.RootFolder; Write-Output "Root Folder Name : $($folder.Name)" } catch { Write-Output "Face an error when retrieving RootFolder object or Folders nested in this RootFolder."; break; } #Creating a file on local folder. Write-Output "`nCreating a file on local folder." $myfile = New-Item -Path .\Temp.txt -ItemType file -Force $textFile = "Congratulations, this file has been updloaded through CSOM & PowerShell";
#Adding data to file Out-File -InputObject $textFile -Append -FilePath $($myfile.FullName) Write-Output "`nAdded Text to Temp file." #Retrieving the root folder and the Sub folders. Write-Output "`nAdding file to $($folder.Name) root folder in List ..." try { $FileInfo = New-Object Microsoft.SharePoint.Client.FileCreationInformation($null); $FileInfo.Content = get-content -encoding byte -path $($myfile.FullName) $FileInfo.Url = "$($myfile.Name)"; $FileInfo.Overwrite = $true; $fileUpload = $folder.Files.Add($FileInfo); $ctx.Load($fileUpload); $ctx.ExecuteQuery(); $ctx.Load($list); $ctx.ExecuteQuery(); } catch { Write-Output "... Face an issue when updloading file to the $ListTitle Doc Library."; break } Write-Output "File was added sucessfully." Write-Output "Now List contains: $($list.ItemCount) items. |
You can find the script attached to this post in "SPO_CreateListItem.zip".
Thanks to Vincent Runge for having reviewed my post.
Dominique VIVES
Comments
- Anonymous
January 01, 2003
@Chris, you can add a app using the below code
#Admin User Principal Name
$admin = 'Chendrayan@domain.OnMicrosoft.Com'
#Get Password as secure String
$password = Read-Host 'Enter Password' -AsSecureString
#Get the Client Context and Bind the Site Collection
$context = New-Object Microsoft.SharePoint.Client.ClientContext($site)
#Authenticate
$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($admin , $password)
$context.Credentials = $credentials
$context.Web.LoadAndInstallApp([System.IO.File]::OpenRead('C:TempFile.app'))
$context.ExecuteQuery() - Anonymous
July 04, 2014
Although this Primarily relates to O365 - I have been able to amend the above example (only slightly) to work flawlessly on SP2010 - something that I have been Struggling with for a while.
Thank you
Ryan - Anonymous
January 09, 2015
I have been able to work with the code above, I was wondering if you have to ability to add an app to a sharepoint online instance subsite, via the powershell interface? I have not been able to figure this out. - Anonymous
June 10, 2015
Very useful post - thanks a lot. I have a follow up question to the above. We have an AppCatalog with a bunch of purchased and homegrown apps. From what I can tell, "$context.Web.LoadAndInstallApp" uploads a ".app" file and then adds it to the site.
What I need is a way to script installing an app from our AppCatalog to all sites in a site collection. Basically, automate a site owner going to Site Contents, clicking "Add an app", picking the app, accepting its terms and then adding it. How would I accomplish this? Thanks in advance.