Try the desktop-based Microsoft 365 Reporting and Management tool from Specmasoft to manage SPO site collections, sites, and sub-sites. This tool offers a variety of pre-configured SPO reports and helps you manage sites in bulk, including external file sharing settings, sharing permissions, hub site associations, and more. Additionally, you can manage site collection administrators and group memberships. Read more ยป
In this post, we will explore how to retrieve all site collections and get their sub-sites recursively with the PnP PowerShell module. Before proceeding, install the latest PnP PowerShell module.
First, we need to connect the Site collection with the PnP module to retrieve subsites. The below command connects a site and lists the associated sub-sites.
#Connect to Site collection (parent or root site)
Connect-PnPOnline -Url "https://contoso.sharepoint.com/sites/test_site"
#Get sub sites
Get-PnPSubWeb
By default, the Get-PnPSubWeb command retrieves first-level sub-sites from the connected Site Collection. We can retrieve all the subsites recursively by using the -Recurse parameter.
Get-PnPSubWeb -Recurse
Get All Sites and Sub Sites in SharePoint Online using PnP PowerShell
The above command retrieves sub-sites only from the given site collection. If you want to get sub-sites from all the site collections, we need to connect the SharePoint admin center site and retrieve all sites collections and loop the sites collections one by one to get their sub-sites.
Run the following commands after replacing your tenant name in the SharePoint Online admin center URL.
#Provide your SharePoint Online Admin center URL
$AdminSiteURL = "https://contoso-admin.sharepoint.com"
#$AdminSiteURL = "https://<Tenant_Name>-admin.sharepoint.com"
#Get SharePoint Admin User Credentials
$Cred = Get-Credential
#Connect to SharePoint Admin Site
Connect-PnPOnline -Url $AdminSiteURL -Credentials $Cred
#Get all site collections
$Sites = Get-PnPTenantSite
#The below command gets only modern Team & Communication sites
#$Sites = Get-PnPTenantSite | Where -Property Template -In ("GROUP#0", "SITEPAGEPUBLISHING#0")
$AllSites = @()
$i = 0;
$TotoalSites = $Sites.Count
#Enumerate site collections and get sub sites recursively
ForEach($Site in $Sites)
{
$i++;
Write-Progress -activity "Processing $($Site.Url)" -status "$i out of $TotoalSites completed"
$SubWebs=$null;
Try
{
#Connect to site collection
$SiteConnection = Connect-PnPOnline -Url $Site.Url -Credentials $Cred
#Get the sub sites of the site collection
$SubWebs = Get-PnPSubWeb -Recurse -Connection $SiteConnection
Disconnect-PnPOnline -Connection $SiteConnection
}
catch{
Write-Host "Error occured $($Site.Url) : $_.Exception.Message" -Foreground Red;
}
#Add site collection in AllSites list
$AllSites += New-Object PSObject -property $([ordered]@{
SiteName = $Site.Title
SiteURL = $Site.Url
IsSubSite = $false
HasSubSites = if ($SubWebs -and $SubWebs.Count -gt 0) { $true } Else {$false}
SiteCollectionName = $Site.Title
SiteCollectionURL = $Site.Url
})
if ($SubWebs -and $SubWebs.Count -gt 0) {
#Enumerate sub sites and add in AllSites list
ForEach($SubSite in $SubWebs)
{
$AllSites += New-Object PSObject -property $([ordered]@{
SiteName = $SubSite.Title
SiteURL = $SubSite.Url
IsSubSite = $true
HasSubSites = $false
SiteCollectionName = $Site.Title
SiteCollectionURL = $Site.Url
})
}
}
}
#Display all site collections and sub sites
$AllSites | Select SiteName,SiteURL,IsSubSite
Export all Site Collections and their Sub-Sites
The above commands store the site details in the array object “$AllSites“. From this array object, we can export the result to a CSV file.
$AllSites | Export-CSV "C:\AllSites-and-SubSites.CSV" -NoTypeInformation -Encoding UTF8
List Site Collections that have subsites
We can generate the required report from the result array “$AllSites”. Run the below command to list the site collections that have associated sub-sites.
$AllSites | Where-Object { $_.HasSubSites -eq $True} | Select SiteName, SiteURL, SiteCollectionName, SiteCollectionUrl
List only sub-sites
Run the below command to list all the sub-site details.
$AllSites | Where-Object { $_.IsSubSite -eq $True} | Select SiteName, SiteUrl, SiteCollectionURL
Thanks Morgan,
That worked a treat!
I have an interesting dilemma… I am able to run this to get all of the subwebs and information with no problem (thanks) however, I am trying to filter out Channel Sites (Teams Generated) from standard site owner created subsites… Any chance you have ideas on that?
First, the Team Channel sites are not sub-sites, they are top-level site collections with different site template. You need to install the latest PnP PowerShell module to find the sites that are connected with teams and teams channels. Install the PnP PowerShell module 2.1.0 to get teams-related properties
Release notes: https://github.com/pnp/powershell/releases/tag/v2.1.0
Install-Module PnP.PowerShell -RequiredVersion 2.1.0 -Force
This version (and the latest) supported the properties IsTeamsConnected, IsTeamsChannelConnected, and TeamChannelType when the Get-PnPTenantSite cmdlet is executed.