Get-SPOAllWebs.ps1

##############################
#.SYNOPSIS
#Returns all sites from a supplied context or web.
#
#.DESCRIPTION
#Recursively returns all sites for a supplied context or web object. This will ignore app-based subsites if designated.
#
#.PARAMETER Context
#The context to start at. The root site for lack of a better term.
#
#.PARAMETER Web
#The web to start at.
#
#.PARAMETER MinusAppDomains
#Do not include sites in the return that are part of an application.
#
#.EXAMPLE
#$allwebs = Get-SPOAllWebs -Context $Context
#
#$subSites = Get-SPOAllWebs -web $Context.Web.Webs[5]
#
#.NOTES
#No notes
##############################
Function Get-SPOAllWebs{
    [CmdletBinding()]
    Param(
    [Parameter(ParameterSetName="Context",Mandatory=$true,ValueFromPipeline)]
    [Microsoft.SharePoint.Client.ClientRuntimeContext[]]
    $Context = $Global:SPOCSOMContext,

    [Parameter(ParameterSetName="web",Mandatory=$false,ValueFromPipeline)]
    [Microsoft.SharePoint.Client.Web]
    $Web,

    [Parameter(ParameterSetName="web")]
    [Parameter(ParameterSetName="Context")]
    [Switch]
    $MinusAppDomains
    
    )

    Begin{
        [Microsoft.SharePoint.Client.Web[]] $results = @()

        $regex = "https:\/\/\w+\.sharepoint\.com"
    }
    Process{

        #If no web was passed, get the initial web from the context.
        If(-not $web){
            Write-Verbose -Message "Received Context. Get web from context."
            $web = Get-SPOWeb -Context $Context
            $web | Initialize-SPOCSOMObjectProperty -PropertyName "HasUniqueRoleAssignments"
        }

        #Add the web to the results.
        Write-verbose -Message "Adding $($Web.url) to results"
        $results += $web
        Write-Verbose -Message "Getting $($Web.url) subsites."

        #initialize the subwebs collection on this specific web.
        $subWebs = Get-SPOSubWebs -web $web

        #If there are subsites, call this function for each subsite.
        if($subWebs.Count -ne 0){
            Write-Verbose -Message "Subsites found in $($Web.url)"
            foreach($sw in $subWebs){
                $results += Get-SPOAllWebs -web $sw
            }
        }

        #No subsite found. Nothing do but report verbosely about it.
        else{
            Write-Verbose -Message "No subsites found in $($Web.url)."
            Write-Verbose -Message "##############End of Recursion Loop##############"
        }
    }
    End{

        #return the results. remove app domains if requested.
        Write-Verbose -Message "Returning Results from $($Web.url)"
        if($MinusAppDomains){
            return ,($results | Where-Object {$_.Url -match $regex})
        }
        Else{
            return ,$results
        }

    }
}