Microsoft SharePoint

SharePoint is a web-based collaborative platform that integrates natively with Microsoft 365. SharePoint is primarily sold as a document management and storage system, although it is also used for sharing information through an intranet, implementing internal applications, and for implementing business processes.

SharePoint Online Management Shell

The SharePoint Online Management Shell is a Windows PowerShell module that you can use to manage SharePoint settings at the organization level and site collection level.

❗ To use SharePoint Online PowerShell commands, you must have the SharePoint Admin role or Global Administrator role in Microsoft 365.

Installation

Open PowerShell with administrative privileges.

powershell
Install-Module -Name Microsoft.Online.SharePoint.PowerShell

For the current user when no admin rights

Install-Module -Name Microsoft.Online.SharePoint.PowerShell -Scope CurrentUser

Update

Update-Module -Name Microsoft.Online.SharePoint.PowerShell
Get-Module -Name Microsoft.Online.SharePoint.PowerShell -ListAvailable | Select Name,Version

Connect

You need the “-admin” in the URL.

Connect-SPOService -Url https://<YOUR-COMPANY>-admin.sharepoint.com
Connect-SPOService -Url https://<YOUR-COMPANY>-admin.sharepoint.com -Credential my.user@<YOUR-COMPANY>.com

Older authentication method.

Connect-SPOService -Credential $creds -Url https://<YOUR-COMPANY>-admin.sharepoint.com -ModernAuth $true -AuthenticationUrl https://login.microsoftonline.com/organizations

List all sites

Open PowerShell with administrative privileges.

Import-Module Microsoft.Online.SharePoint.PowerShell

Run the following command to get all sites:

Get-SPOSite

SharePoint REST APIs

Values for contentclass:

  • STS_ListItem: List items in SharePoint lists. This includes individual items within document libraries, custom lists, calendar events, tasks, announcements, etc.
  • STS_Web: Sub-sites or child sites within a SharePoint site collection. These are individual sites that exist within a site hierarchy.
  • STS_List: SharePoint lists, including document libraries, custom lists, calendars, discussion boards, surveys, etc.
  • STS_Document: Individual documents within document libraries. This is often used in conjunction with STS_ListItem for finer-grained classification of content.
  • STS_Page: Wiki pages or web part pages within SharePoint sites.
  • STS_SiteAdminWebTemplate: Administrative sites or central administration sites within a SharePoint farm. These sites are used for managing and configuring SharePoint at a higher level.
  • STS_User: User profiles or user-related information within SharePoint. This can include user profiles, user properties, and other user-related data.
  • STS_Group: SharePoint groups or security groups within SharePoint. These are used for managing permissions and access control within SharePoint sites.

List all sites and privacy setting

💡 Result might be in XML. For JSON, add HTTP header “Accept: application/json” to the HTTP request.

https://<YOUR-COMPANY>.sharepoint.com/_api/search/query?querytext='contentclass:STS_Site'&selectproperties='Title,Path,SitePrivacy'&rowlimit=1000

sharepoint-sites-enum.py

List all SharePoint sites and their privacy setting (when explicitly set). Also makes an HTTP request to validate.

import requests

# Remove warnings: InsecureRequestWarning: Unverified HTTPS request
requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)

# Construct the URL to get all sites and subsites
# STS_Site is for SharePoint sites, STS_Web is for subsites
api_url = f"https://<REPLACE ME!>.sharepoint.com/_api/search/query?querytext='contentclass:STS_Site OR contentclass:STS_Web'&selectproperties='Title,Path,SitePrivacy'&rowlimit=1&startrow="

# Required cookies: rtFa and FedAuth
rtFa = "REPLACE ME!"
FedAuth = "REPLACE ME!"

headers = {
'Cookie' : 'rtFa=' + rtFa + '; FedAuth=' + FedAuth,
'Accept': 'application/json'
}

def get_response_code(url):
    try:
        response = requests.get(url, verify=False, headers=headers)
        return str(response.status_code) + ' ' + response.reason
    except requests.RequestException as e:
        print("Error:", e)
        return "ERROR"

i = 0
completed = False
print("URL, Title, SitePrivacy, Server response")

with open('sharepoint-sites.csv', 'w', encoding="utf-8") as file:
  file.write("URL; Title; SitePrivacy; Server response\n")

  while(not completed):
      try:
        response = requests.get(api_url + str(i), verify=False, headers=headers)

        if response.status_code == 200:
          data = response.json()
          row_count = data['PrimaryQueryResult']['RelevantResults']['RowCount']    
          sites = data['PrimaryQueryResult']['RelevantResults']['Table']['Rows']
        
          for site in sites:
            title = next(item['Value'] for item in site['Cells'] if item['Key'] == 'Title')
            url = next(item['Value'] for item in site['Cells'] if item['Key'] == 'Path')
            privacy = next(item['Value'] for item in site['Cells'] if item['Key'] == 'SitePrivacy')
            code = response_code = get_response_code(url)
              
            print(f"{i}: {url}; {title}; {privacy}; {code}")
            file.write(f"{url}; {title}; {privacy}; {code}\n")

          if row_count < 1:
            completed = True
      except requests.RequestException as e:
         print("Error:", e)
         print(api_url + str(i))
         file.write(api_url + str(i) + '; ERROR; None; ERROR')

      i+=1

      if i >= 50000: # Safeguard
         completed = True