I want to retrieve all site collections in an Online tenant through Visual Studio:

  • I can do it via Powershell: get-sposite
  • on-premise server : Get-SPSite
  • on-premise again: var sites = webapp.Sites.Where(i=>i.url.StartsWith(webapp.url + "/departments/")); http://sharepoint.stackexchange.com/questions/7137/how-can-i-list-the-site-collections-under-a-given-url-path

I can use the following code to iterate through sites within one site collection, so I thought I could try "https://domain.sharepoint.com/sites/" but of course it doesn't work, because such site doesn't exist.

"The remote server returned an error: (401) Unauthorized." at context.ExecuteQuery():

ClientContext context = new ClientContext(https://domain.sharepoint.com/sites/);
            context.Credentials = new SharePointOnlineCredentials(userName2, password2);

            Web site = context.Web;


            string allsitecollections = "";

            for (int i = 0; i < context.Web.Webs.Count; i++)

                allsitecollections = allsitecollections + context.Web.Webs[i].Url + "\n";


Is there a way to retrieve the site collections with C# or should I resort to http://blogs.msdn.com/b/kebab/archive/2014/04/28/executing-powershell-scripts-from-c.aspx ?

  • online tenant? Do we know the WebApplication? Jul 3, 2014 at 10:58
  • 2
    @VarunVerma Webapplications is not really a thing visible to the tenants in Office 365 SharePoint Online Jul 3, 2014 at 13:00
  • @RobertLindgren okiz :) Jul 4, 2014 at 4:08

4 Answers 4


You can do it all from C# using the excellent post found here.

This example is, I believe, from within a SharePoint app but you can do it similarly from a console app.

First you'll need to add a reference to Microsoft.Online.SharePoint.Client.Tenant.dll which you can find here (C:\Program Files\SharePoint Client Components\Assemblies) after installing the SharePoint Server 2013 Client Components SDK.

The only real difference in the code is how you create your ClientContext and pass credentials. Here is a full example:

siteUrl = "https://yourtenantname-admin.sharepoint.com";
userName = "[email protected]";
password = "password";

using (ClientContext clientContext = new ClientContext(siteUrl))
    SecureString passWord = new SecureString();
    foreach (char c in password.ToCharArray()) passWord.AppendChar(c);
    clientContext.Credentials = new SharePointOnlineCredentials(userName, passWord);

    var tenant = new Tenant(clientContext);
    SPOSitePropertiesEnumerable spp = tenant.GetSiteProperties(0, true);


    foreach (SiteProperties sp in spp)

By using

SPOSitePropertiesEnumerable spp = tenant.GetSiteProperties(0, true);

you will get limited to 300 site collections only.

I shared my solution here to get all the site collections here. https://stackoverflow.com/questions/24405584/sharepoint-csom-retrieving-site-collections-limited-to-300/24406495?noredirect=1#comment40072226_24406495

SPOSitePropertiesEnumerable spp = null;
var tenant = new Tenant(ctx);
int startIndex = 0;

while (spp == null || spp.Count > 0)
    spp = tenant.GetSiteProperties(startIndex, true);

    foreach (SiteProperties sp in spp)
    siteCols.Add(new SiteCol(sp.Title, sp.Url));

    startIndex = siteCols.Count;

You would have to resort to calling the PowerShell, and using the Get-SPOSite cmdlet to get all the site collections.

The following will return the url of all site collections:

var runspace = RunspaceFactory.CreateRunspace();
var pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript( "Import-Module Microsoft.Online.SharePoint.PowerShell" );

pipeline.Commands.AddScript( "$password = \"" + password + "\"" +
                             " | ConvertTo-SecureString -AsPlainText -Force" );
pipeline.Commands.AddScript( "$spoCreds = New-Object System.Management.Automation.PSCredential(\"" +
                             userName + "\", $password)" );

pipeline.Commands.AddScript( "Connect-SPOService -Url " + adminUrl + " -Credential $spoCreds" );

pipeline.Commands.AddScript( "Get-SPOSite" );
var results = pipeline.Invoke();
var stringBuilder = new StringBuilder();
foreach ( var psObject in results )
    var site = psObject.Members["Url"];

    stringBuilder.AppendLine( site.Value.ToString() );
Console.WriteLine( stringBuilder.ToString() );

I had no idea what I was doing when I originally wrote this, so it can probably be done better.


tenant.GetSiteProperties(startIndex, true); will only return classic sites. To return modern sites, you can utilize the Office PnP GetSiteCollections method.

var tenant = new Tenant(ctx);
var sites = tenant.GetSiteCollections(0, 5000, true);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.