Build-PorteoSiteFromTemplate.ps1

<#
    .Synopsis
        Build-PorteoSite -TenantUrl "https://mysite-admin.sharepoint.com" -Credentials (Get-Credential) `
                     -SiteName "Site1" -Title "The Site" -Owner "name@mysite.onmicrosoft.com" -Type "TeamSite" `
                     -SrcConnection $srcConnection

    .Description
        This function builds a *Porteo* site. A *Porteo* site is a ***SimpleSharepoint*** base site, based on
        either a **TeamSite** or **ComunicationSite** template type and has the following ***SimpleSharepoint*** lists:

        * Site Assets (SiteAssets)
        * Documents (Shared Documents)
        * Journal
        * Requests
        * SiteCollectionList
        * Links
        * SubsiteLists

        At this point, you would create this base site, then add contents to the above lists. You may
        also add some other lists, add to the _SiteAssets_ and any other *Pages* with content and
        branding. This created and modified site will be used to provision other sites on other
        tenants.

        To provision a new site, you extract a template from the desired site using
        Get-SSPSiteTemplate with a file name (.pnp extension)
        and now use the `-Template` argument to specify this file and
        use the `-TenantUrl` and `-Credentials` arguments to create the site on the target tenant. See
        the series of Examples below to see the process and sequence of operations.

        Then the target site is provisioned from the site associated with the template file.

        The site Pages are copied as well as the Pages' contents. Furthermore, the *Porteo* standard lists,
        which are listed above, have their structure and contents copied.

        The examples provide in sequence the process by which you may create a base *Porteo* site, modify it,
        and then use the result to provision another site.

        ***Note***: If the tenant site already exists, this function will return with an Error. You must either
        delete the target site first, or give use a different name.
    .Parameter TenantUrl
        This parameter holds the tenant adminstrative site url, e.g. https://mysite-admin.sharepoint.com
    .Parameter Credentials
        This parameter holds the credentials for the tenant adminstrator.
    .Parameter SiteName
        This parameter holds the name of the site to be created.
    .Parameter Title
        This parameter holds the title for the site to be created.
    .Parameter Type
        This paramter holds the type of site to be created, e.g. TeamSite or CommunicationSite.
    .Parameter Owner
        This paramter holds the owner of the new site, which is an email address.
    .Parameter Template
        This paramter holds the template file.
    .Parameter Lcid
        This paramter holds the language for the new site. Default is "1033" English.
    .Parameter Runs
        This parameter contains a number of runs to use in applying the template to the site.
        It is found that probably due to temporal issues for Sharepoint, that multiple runs
        are necessary. Default is 2.
    .Parameter AddInstalledApps
        This parameter adds any installed apps on the tenant to the site.

    .Example
    $dstCreds = Get-Credential

    Gets the tenant credentials to to build the new site.
    .Example
    $newSiteUrl = Build-PorteoSiteFromTemplate -Template /tmp/template.pnp
                 -TenantUrl "https://client-admin.sharepoint.com" -Credentials $dstCreds `
                 -SiteName "new-site" -Title "The New Site" -Type "TeamSite" `
                 -Owner "admin@company.com"

    Builds the new site "New Site" at https://client.sharepoint.com/sites/new-site and provisions it from the
    template file.

    .Example
    $colorPaletteUrl = Add-SSPThemeToTemplate -Path /tmp/template.pnp -Connection $srcConn
    $newSiteUrl = Build-PorteoSiteFromTemplate -Template /tmp/template.pnp
                 -TenantUrl "https://client-admin.sharepoint.com" -Credentials $dstCreds `
                 -SiteName "new-site" -Title "The New Site" -Type "TeamSite" `
                 -Owner "admin@company.com" -AddInstalledApps $true

    Builds the new site "New Site" at https://client.sharepoint.com/sites/new-site and provisions it from the
    template file using the current theme of the source site that was put into the template file.
#>


function Build-PorteoSiteFromTemplate {
    param(
        [parameter(Mandatory=$true)]
        [string]
        $template,
        [parameter(Mandatory=$true)]
        [string]
        $tenantUrl,
        [parameter(Mandatory=$true)]
        [System.Management.Automation.PSCredential]
        $credentials,
        [parameter(Mandatory=$true)]
        [string]
        $siteName,
        [parameter(Mandatory=$true)]
        [string]
        $title,
        [parameter(Mandatory=$true)]
        [string]
        $owner,
        [parameter(Mandatory=$false,HelpMessage="Default is TeamSite")]
        [string]
        $type = "TeamSite",
        [parameter(Mandatory=$false)]
        [string]
        $lcid = "1033",
        [string]
        $colorPaletteUrl,
        [parameter(Mandatory=$false)]
        $runs = 2,
        [Boolean]
        $addInstalledApps = $false
    )

    $baseUrl = $tenantUrl.Replace("-admin", "")
    $siteurl = "$baseUrl/sites/$siteName"
    Write-Host "Establishing Connection to the $type site '$title' at $siteUrl"
    $connection = Connect-PnPOnline -Url $tenantUrl -Credentials $credentials -ReturnConnection
    $site = Get-PnPTenantSite -Url $siteUrl  -ErrorAction SilentlyContinue
    if (-not $site)
    {
        $handlers = Get-PorteoDefaultHandlers

        Write-Host "Creating $type site '$title' at $siteUrl"
        $site = Add-SSPSite -Owner $owner -SiteUrl $siteUrl -Title $title -SiteName $siteName -Type $type -Lcid $lcid -Connection $connection
        if ($site)
        {
            $siteUrl = $site
            Write-Host "Created $type site $title at $siteUrl"
            Write-Host "Provisioning $type site $siteUrl"

            $destConn = Connect-PnPOnline -Url $siteUrl -Credentials $credentials -ReturnConnection
            $ignore = Set-PnpSite -NoScriptSite $false -Connection $destConn

            #$ignore = Add-PorteoSiteDesigns -Type $type -Connection $connection

            Invoke-SSPSiteTemplate -FileName $template -DestConnection $destConn -Runs $runs -Handlers $handlers
            Write-Host "Invoke-SSPSiteTemplate Finished!"

            if ($addInstalledApps)
            {
                $apps = (Get-PnPApp -Connection $connection | Where-Object {$_.InstalledVersion -ne ""})
                $apps | ForEach-Object {
                    Write-Host "Installing App $($_.Id) '$($_.Title)' in site $siteUrl"
                    Install-PnPApp -Identity $_.Id -Connection $destConn
                }
            }

            Write-Host "Provisioned $type site $siteUrl"
            return $siteUrl

        } else {
            Write-Host "Did not create $type site $siteUrl"
        }
    } else {
        Write-Host "Cannot create $type site $siteUrl as it already exists."
    }
}