How to get WebsCount and other details from SharePoint online using Tenant Administration API

This post is a contribution from Mustaq Patel, an engineer with the SharePoint Developer Support team

Prior to CSOM ver 16.1.4727.1000, we can get count of all sites in tenant in SharePoint Online Tenant using SiteProperties.WebsCount. You can find Powershell sample at below link
https://gallery.technet.microsoft.com/office/How-to-get-all-the-tenant-2999c21b

With CSOM ver 16.1.4727.1000 and SPO Service dated 12/20/2016 onwards, SiteProperties.WebsCount alone as in above Powershell will not return correct value. You will see WebsCount is returned as zero. In addition, other properties returned are either zero or not up to date. You can read more on the issue in below forum.
https://sharepoint.stackexchange.com/questions/203198/siteproperties-webscount-property-is-returning-zero-csom/203201

SharePoint Online Product Group changed the implementation of how these Tenant level API works due to performance reasons. Now if we want to retrieve WebsCount and other properties of a site collection, an additional call to Tenant.GetSitePropertiesByUrl is needed and the Property collection acquired from that call needs to be used to get WebsCount and other properties. Below is the working sample.

Assemblies to Reference

 Microsoft.SharePoint.Client.dll

Microsoft.SharePoint.Client.Runtime.dll

The above two assemblies can be found at C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI

 Microsoft.Online.SharePoint.Client.Tenant.dll

This assembly can be found at  C:\Program Files\SharePoint Client Components\16.0\Assemblies)

Below is the code to get the webs count property.

 //Code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.SharePoint.Client;
using Microsoft.Online.SharePoint.TenantAdministration;
using System.Security;

namespace GetWebCountsSPO
{
    class Program
    {
        static void Main(string[] args)
        {
            GetListOfSiteCollections();
            Console.ReadLine();
        }

        private static void GetListOfSiteCollections()
        {
            string SPOAdminSiteUrl = "https://tenantadmin.sharepoint.com";
            string SPAdminUserName = "tenant-admin@domain.onmicrosoft.com";
            string SPAdminPassword = "password";

            try
            {            
                using (ClientContext context = new ClientContext(SPOAdminSiteUrl))
                {                
                    context.Credentials = AuthenticateMySPO(SPAdminUserName, SPAdminPassword);
                    Tenant mytenant = new Tenant(context);

                    
                    SPOSitePropertiesEnumerable allsiteProps = mytenant.GetSitePropertiesFromSharePointByFilters(new SPOSitePropertiesEnumerableFilter
                    {
                        IncludePersonalSite = PersonalSiteFilter.Include,
                    });

                    context.Load(allsiteProps, null); // null means fill all properties
                    context.ExecuteQuery();

                    foreach (var s in allsiteProps)
                    {
                        //this is needed now, earlier WebsCount can be queried via Tenant.GetSiteProperties
                        var sprops = mytenant.GetSitePropertiesByUrl(s.Url, true);
                        context.Load(sprops);
                        context.ExecuteQuery();
                        Console.WriteLine("SiteCollectionURL:" + sprops.Url);
                        Console.WriteLine("WebsCount:" + sprops.WebsCount);
                        Console.WriteLine("StorageUsage:" + sprops.StorageUsage);
                        Console.WriteLine("TimeZoneId:" + sprops.TimeZoneId);
                        Console.WriteLine("LastContentModifiedDate:" + sprops.LastContentModifiedDate);
                    }
                }
            }
           catch (Exception ex)
           {
                Console.WriteLine("Exception:" +ex.message);
           }                   

           Console.WriteLine("Done.");

        }

        static SharePointOnlineCredentials AuthenticateMySPO(string uname, string pwd)
        {
            var securePassword = new SecureString();
            foreach (char c in pwd)
            {
                securePassword.AppendChar(c);
            }

            var onlineCredentials = new SharePointOnlineCredentials(uname, securePassword);
            return onlineCredentials;
        }
    }
}

 

You can also read the above resolution on below blog
https://techcommunity.microsoft.com/t5/SharePoint-Developer/SiteProperties-WebsCount-property-is-returning-zero-CSOM/m-p/36595#M1098