Use powershell to retrieve all subsites for sharepoint online

18,777

For SharePoint Online (SPO) Microsoft released SharePoint Online Management Shell that contains Get-SPOSite cmdlet to return one or more site collections.

Example:

Add-Type –Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll" 
Add-Type –Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"

$AdminUrl = "https://tenant-admin.sharepoint.com/"
$UserName = "[email protected]"
$Password = "password"
$SecurePassword = $Password | ConvertTo-SecureString -AsPlainText -Force
$Credentials = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $userName, $SecurePassword

#Retrieve all site collection infos
Connect-SPOService -Url $AdminUrl -Credential $Credentials
$sites = Get-SPOSite 

How to retrieve all sites via CSOM in PowerShell

Since SharePoint Online Management Shell does not contain any cmdlets for working with sites, we will utilize CSOM API for that purpose. The below function retrieves all the sites in site collection:

function Get-SPOWebs(){
param(
   $Url = $(throw "Please provide a Site Collection Url"),
   $Credential = $(throw "Please provide a Credentials")
)

  $context = New-Object Microsoft.SharePoint.Client.ClientContext($Url)  
  $context.Credentials = $Credential 
  $web = $context.Web
  $context.Load($web)
  $context.Load($web.Webs)
  $context.ExecuteQuery()
  foreach($web in $web.Webs)
  {
       Get-SPOWebs -Url $web.Url -Credential $Credential 
       $web
  }
}

Example: print all sites for a site collection in SPO

Add-Type –Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll" 
Add-Type –Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll" 


$UserName = "[email protected]"
$Password = "password"
$SecurePassword = $Password | ConvertTo-SecureString -AsPlainText -Force
$SPOCredentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $SecurePassword)

$AllWebs = Get-SPOWebs -Url 'https://tenant.sharepoint.com' -Credential $SPOCredentials
$AllWebs | %{ Write-Host $_.Title }

Result

By combining both techniques you could achieve the desired results:

#Retrieve all site collection infos
Connect-SPOService -Url $AdminUrl -Credential $Credentials
$sites = Get-SPOSite 

#Retrieve and print all sites
foreach ($site in $sites)
{
    Write-Host 'Site collection:' $site.Url     
    $AllWebs = Get-SPOWebs -Url $site.Url -Credential $SPOCredentials
    $AllWebs | %{ Write-Host $_.Title }   
    Write-Host '-----------------------------' 
}    
Share:
18,777
Admin
Author by

Admin

Updated on June 28, 2022

Comments

  • Admin
    Admin almost 2 years

    I'm trying to write a powershell script to retrieve all site collections, their groups and subsites from our SharePoint Online tenancy. So far I've been able to get all sites, their groups and the users in each group. I'm just having trouble getting the subsites and identifying any lists with unique permissions (and retrieving those permissions hopefully!)

    So far I have this to get the lists:

    Add-Type –Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll" 
    Add-Type –Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll" 
    
    $password = Read-Host -Prompt "Enter password" -AsSecureString
    $credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials("username", $password)
    
    $siteURL = "https://site/sites/test"
    
    $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($siteUrl)  
    $ctx.Credentials = $credentials 
    $web = $ctx.Web
    
    $lists = $web.Lists 
    $ctx.Load($lists)
    $ctx.ExecuteQuery()
    
    foreach($list in $lists)
    {
        Write-Host $list.Title
    }
    

    and this to get site groups and users:

    Connect-SPOService –url https://site-admin.sharepoint.com
    
    
    $sites = Get-SPOSite -Detailed
    
    foreach ($site in $sites)
    {
    
        Write-Host $site.Title
        $siteGroups = Get-SPOSiteGroup -Site $site.Url
    
        foreach ($group in $siteGroups)
            {
                  $users = Get-SPOUser -Site $site.Url  -Group $group.Title -Limit All |ft -wrap 
                  $url = $site.Url
                  $groupName = $group.Title
                  Write-Host $groupName + ' ' + $group.Users
    
    
    
            }
    
    
    } 
    

    So for the lists I tried using $list.HasUniqueRoleAssignments to determine if the list returned has unique permissions but it always seems to return false even if there are unique permissions. For the subsites I can get a count of the subsites, but how do I get the URL?

    Thanks in advance!

    EDIT: So I've been able to get the URL of the subsites using the client context code I used to get the lists:

    $subs = $web.Webs
    $ctx.Load($subs)
    $ctx.ExecuteQuery()
    
    foreach($sub in $subs)
    {
        Write-Host $sub.Url
    }
    

    Still stuck with getting permissions though...

  • Haymak3r
    Haymak3r over 7 years
    How might I be able to extend this in order to make feature updates for each of these sites? (i.e. $site.Features.Add($featureguid, $true, [Microsoft.SharePoint.Client.FeatureDefinitionScope]::None);‌​)