Also for OneDrive for Business site collections in the tenant, the user who is owner of the site collection is the only person who has site collection admin rights on it by default. This can be a problem for compliance and e-discovery reasons. You might be in a situation where you need to give site collection admin rights to a compliance manager or a global administrator on all the OneDrive for Business sites in a tenant.
In this post, lets have a look at how you can make a user a site collection admin on all the site collections in a tenant as well as on all the OneDrive for Business site collections in the tenant.
Some notes:
1) For now, this only works with SharePoint Online/Office 365.
2) You will need the SharePoint Online Client Side Object Model Nuget package
3) By changing a parameter in the SetSiteAdmin function, you can also remove a user from the site collection admins of all site collections.
4) The user who runs this code will need Tenant Administrator rights on the Tenant.
1) Add a site collection admin to all site collections in a tenant:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Tenant Details | |
string tenantAdminUrl = "https://yoursite-admin.sharepoint.com/"; | |
string tenantAdminLoginName = "admin@yoursite.onmicrosoft.com"; | |
string tenantAdminPassword = "password"; | |
using (ClientContext clientContext = new ClientContext(tenantAdminUrl)) | |
{ | |
//Credentials | |
var passWord = new SecureString(); | |
foreach (char c in tenantAdminPassword.ToCharArray()) passWord.AppendChar(c); | |
clientContext.Credentials = new SharePointOnlineCredentials(tenantAdminLoginName, passWord); | |
var tenant = new Tenant(clientContext); | |
//Get login name of the current user | |
var currentUser = clientContext.Web.CurrentUser; | |
clientContext.Load(currentUser, u => u.LoginName); | |
int startIndex = 0; | |
SPOSitePropertiesEnumerable siteProperties; | |
do | |
{ | |
//Get urls of site collections in the tenant in batches of 300 (Does not include the OneDrive for Business sites) | |
siteProperties = tenant.GetSiteProperties(startIndex, false); | |
clientContext.Load(siteProperties, siteProps => siteProps.Include(site => site.Url)); | |
clientContext.ExecuteQuery(); | |
//Iterate the site collectio urls | |
foreach (var siteProperty in siteProperties) | |
{ | |
try | |
{ | |
//assign the specified user (current user in this case) as the site collection admin. | |
tenant.SetSiteAdmin(siteProperty.Url, currentUser.LoginName, true); | |
//Set the last parameter to false if you want to remove the user from the site collection admins | |
clientContext.ExecuteQuery(); | |
System.Console.WriteLine(siteProperty.Url); | |
} | |
catch (Exception ex) | |
{ | |
System.Console.WriteLine("Error on: " + siteProperty.Url + " " + ex.Message); | |
} | |
} | |
startIndex += 300; | |
} while (siteProperties.Count >= 300); | |
} |
2) Add a site collection admin to all the OneDrive for Business site collections in a tenant:
This takes a bit more work. Here are all the things we need to do:
1) Get the account names of the users in a tenant using People Search. Now bear in mind that search has a limitation of returning a maximum of 500 rows on SharePoint Online. That will be 500 users in our case. So if your tenant as more than 500 users, you will need to call search in batches of 500 to get the account names of all the users.
2) Once we have the account names of the users, we need to get the url of their OneDrive for Business sites. We can do this by querying the CSOM UserProfile API
3) After getting the OneDrive for Business site urls, all we need to do is use the same Tenant.SetSiteAdmin function as above.
Here is the complete code for that:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.Online.SharePoint.TenantAdministration; | |
using Microsoft.SharePoint.Client; | |
using Microsoft.SharePoint.Client.Search.Query; | |
using Microsoft.SharePoint.Client.UserProfiles; | |
using System; | |
using System.Collections.Generic; | |
using System.Security; | |
namespace CSOM.Console.Test | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
//Tenant Details | |
string tenantAdminUrl = "https://tenantName-admin.sharepoint.com/"; | |
string tenantAdminLoginName = "admin@tenantName.onmicrosoft.com"; | |
string tenantAdminPassword = "password"; | |
string mySiteHostUrl = "https://tenantName-my.sharepoint.com"; | |
using (ClientContext clientContext = new ClientContext(tenantAdminUrl)) | |
{ | |
//Credentials | |
var passWord = new SecureString(); | |
foreach (char c in tenantAdminPassword.ToCharArray()) passWord.AppendChar(c); | |
clientContext.Credentials = new SharePointOnlineCredentials(tenantAdminLoginName, passWord); | |
//Get accountnames of users in the tenant | |
var accountNames = GetUserAccountNames(clientContext); | |
//Get OD4B site urls | |
var OD4BSites = GetUserOD4BSites(mySiteHostUrl, clientContext, accountNames); | |
//Set User as Site collection admin on the OD4B sites. | |
SetAdminOnOD4BSites(clientContext, OD4BSites); | |
System.Console.ReadKey(); | |
} | |
} | |
private static List<string> GetUserAccountNames(ClientContext clientContext) | |
{ | |
//Use search to get the AccountNames of users in a tenant. | |
var keywordQuery = new KeywordQuery(clientContext); | |
keywordQuery.QueryText = "*"; | |
keywordQuery.SourceId = new Guid("b09a7990-05ea-4af9-81ef-edfab16c4e31"); | |
keywordQuery.SelectProperties.Add("AccountName"); | |
keywordQuery.BypassResultTypes = true; | |
var searchExecutor = new SearchExecutor(clientContext); | |
var searchResults = searchExecutor.ExecuteQuery(keywordQuery); | |
clientContext.ExecuteQuery(); | |
var accountNames = new List<string>(); | |
if (searchResults.Value.Count > 0 && searchResults.Value[0].RowCount > 0) | |
{ | |
foreach (var resultRow in searchResults.Value[0].ResultRows) | |
{ | |
accountNames.Add(resultRow["AccountName"].ToString()); | |
} | |
} | |
return accountNames; | |
} | |
private static List<string> GetUserOD4BSites(string mySiteHostUrl, ClientContext clientContext, List<string> accountNames) | |
{ | |
var OD4BSites = new List<string>(); | |
foreach (var accountName in accountNames) | |
{ | |
// Get the people manager instance | |
var peopleManager = new PeopleManager(clientContext); | |
// Get the OneDrive for Business Site Url | |
var OD4BSite = peopleManager.GetUserProfilePropertyFor(accountName, "PersonalSpace"); | |
clientContext.ExecuteQuery(); | |
OD4BSites.Add(mySiteHostUrl + OD4BSite.Value); | |
} | |
return OD4BSites; | |
} | |
private static void SetAdminOnOD4BSites(ClientContext clientContext, List<string> OD4BSites) | |
{ | |
var tenant = new Tenant(clientContext); | |
//Get login name of the current user | |
var currentUser = clientContext.Web.CurrentUser; | |
clientContext.Load(currentUser, u => u.LoginName); | |
clientContext.ExecuteQuery(); | |
//Iterate the site collectio urls | |
foreach (var OD4BSite in OD4BSites) | |
{ | |
try | |
{ | |
//assign the specified user (current user in this case) as the tenant admin. | |
tenant.SetSiteAdmin(OD4BSite, currentUser.LoginName, true); | |
//Set the last parameter to false if you want to remove the user from the site collection admins | |
clientContext.ExecuteQuery(); | |
System.Console.WriteLine(OD4BSite); | |
} | |
catch (Exception ex) | |
{ | |
System.Console.WriteLine("Error on: " + OD4BSite + " " + ex.Message); | |
} | |
} | |
} | |
} | |
} |
There is also another way to do the same thing where you get the OneDrive for Business site urls from the UserProfileService.asmx and then use the Set-SPOUser SharePoint Online PowerShell cmdlet to set the user as the site collection admin. Here are the details for that https://technet.microsoft.com/en-us/library/dn765092.aspx
Hope you found this article useful!