Accéder au contenu principal

Office 365: Modifier les jeux de couleur dans les Thèmes des pages classiques de SharePoint Online

 Dans un précédent post, nous avons vu comment configurer et implémenter un Theme utilisable dans les Modern Site Page via un script PowerShell:

La question du systeme de gestion de theme en mode classique reste pourtant d'actualité à travers le lien "Classic change the look options" disponible dans la sélection des thèmes modernes. Cette option vous ammene directement dans la page des gestion de theme de SharePoint 2013.

Du point de vue administrateur, la gestion des thèmes est différentes entre la version moderne et classique
  - Modern site:
     - Au niveau du Tenant:
          -> Activation de la selection des thèmes
          -> Désactivation des sélections de couleur de base
          -> Ajouter le nouveau jeu de couleurs Corporate
     - Au niveau de la collection de sites:
          -> Rien de possible
     - Au niveau SPWeb (pour chaque site ou sous-site)
          -> Sélection de la couleur utilisée
  - Classic site:
     - Au niveau du Tenant: Rien de possible
     - Au niveau de la collection de sites: Rien de possible sauf la remontée des fichiers techniques du thème
     - Au niveau SPWeb (pour chaque site ou sous-site)
            -> Ajouter le nouveau Theme Corporate
           -> Suppression des autres thèmes de base

Il est utile de déléguer la gestion des couleurs (et le thème) des sites au propriétaires de ceux-ci, mais il faut alors leur proposer la mise en place du jeu de couleur corporate s'ils le souhaitent.

Ce script permet donc de mettre en place les thèmes classiques pour tous les sites et sous-sites d'un ensemble de collections de site suivant le filtrage choisi.
C'est possible au niveau des sites SharePoint basiques, des groupes office 365 ou tout autre filtrage voulu.

Vous devez préparer les fichiers de resource (spconf, spcolor, backgroundfile and logo file).
 
Vous pouvez utiliser ce script PowerShell script comme vous le souhaitez en l'adaptant à votre besoin, mais il a fonctionné dans un tenant avec plus de 2000 collections de site et de très nombreux sous-sites associés.


[string]$username = "admin@tenant.onmicrosoft.com"
[string]$PwdTXTPath = "C:\SECUREDPWD\ExportedPWD-$($username).txt"

$secureStringPwd = ConvertTo-SecureString -string (Get-Content $PwdTXTPath)
$adminCreds = New-Object System.Management.Automation.PSCredential $username, $secureStringPwd

[string]$ThemeFileFolder = "D:\THEME_FILES\CORP_SPO_THEME\"
[string]$ThemeName = "CORP Theme"
[string]$AssetListNameURL = "SiteAssets"
[string]$CORPFoldername = "CORPTheme"
[string]$IntranetMasterPage = "seattle.master"
[string]$ExtranetMasterPage = "oslo.master"

[string]$ThemeFileSPFont = "Fontscheme-CORP.spfont"
[string]$ThemeFileSPColor = "Palette-CORP.spcolor"
[string]$ThemeFileLogo = "logo_CORP.png"
[string]$ThemeFileIntranetBG = "INTRANET_CORP.jpg"
[string]$ThemeFileExtranetBG = "EXTRANET_CORP.jpg"

function Load-DLLandAssemblies
{
     [string]$defaultDLLPath = ""

    # Load assemblies to PowerShell session

    $defaultDLLPath = "C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.SharePoint.Client.dll"
    [System.Reflection.Assembly]::LoadFile($defaultDLLPath)

    $defaultDLLPath = "C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.SharePoint.Client.Runtime.dll"
    [System.Reflection.Assembly]::LoadFile($defaultDLLPath)

    $defaultDLLPath = "C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.Online.SharePoint.Client.Tenant.dll"
    [System.Reflection.Assembly]::LoadFile($defaultDLLPath)
}

function IfThemeExists($Myctx, $list, $themeName)
{
    [int]$ReturnValue = 0
    $caml="<View><Query><Where><Eq><FieldRef Name='Name' /><Value Type='Text'>$themeName</Value></Eq></Where></Query></View>";
    $cquery = New-Object Microsoft.SharePoint.Client.CamlQuery
    $cquery.ViewXml=$caml
    $listItems = $list.GetItems($cquery)
    $Myctx.Load($listItems)
    $Myctx.ExecuteQuery()
    if($listItems.Count > 0)
    {
         $ReturnValue = 0;
    }
    else
    {
        foreach ($targetListItem in $listItems)
        {
            $ReturnValue = $targetListItem["ID"]
        }
    }
    return $ReturnValue
}

function Upload-Specific-File($CompleteFilePath, $spoWebContext, $MyfolderURL )
{   
    $Localfile = get-item $CompleteFilePath
   
    [string]$MyNewFileURL = -join($MyfolderURL, "/", $Localfile.Name)
    write-host "CORP File URL Uploaded:", $Localfile.FullName, " - Url:", $MyNewFileURL
    [Microsoft.SharePoint.Client.File]::SaveBinaryDirect($spoWebContext, $MyNewFileURL, $Localfile.OpenRead(), $true)
}

#Custom Function to Add a new Theme in the old classic format
Function AddNewCorpThemeInSPweb($myctx, $myCurrentWeb, [string]$RootOrSubstite, [string]$RootSiteRelativeURL, [string]$ExtranetSharing)
{
    Try
    {
        [string]$tempSourcePath = ""
        [string]$tempDestinationPathSiteAsset = ""
        [string]$tempDestinationPathTheme = ""
        [string]$masterPageUrl = ""
        $myUploadedFile
       
         [string]$tempPathBG = ""
        [string]$tempPathFont = ""
        [string]$tempPathPalette = ""

        $tempDestinationPathSiteAsset = -join($myCurrentWeb.ServerRelativeUrl, "/", $AssetListNameURL, "/", $CORPFoldername)
        $tempDestinationPathTheme = -join($myCurrentWeb.ServerRelativeUrl, "/_catalogs/theme/15")

        Write-Host " ---------------------------------------------- "
        Write-Host " >>>> UPLOAD THE THEME FILES INTO THE ROOT SITE: ", $myCurrentWeb.ServerRelativeUrl  -foregroundcolor yellow
        #Deploy Custom Logo
        $tempSourcePath = -join($ThemeFileFolder, $ThemeFileLogo)
        Upload-Specific-File  $tempSourcePath $myctx $tempDestinationPathSiteAsset
         Write-Host "     >>>> file uploaded from:", $tempSourcePath, "- to:", $tempDestinationPathSiteAsset

        #Deploy BackGround
        $tempSourcePath = -join($ThemeFileFolder, $ThemeFileIntranetBG)
        Upload-Specific-File  $tempSourcePath $myctx $tempDestinationPathSiteAsset
        Write-Host "     >>>> file uploaded from:", $tempSourcePath, "- to:", $tempDestinationPathSiteAsset
       
        $tempSourcePath = -join($ThemeFileFolder, $ThemeFileExtranetBG)
        Upload-Specific-File  $tempSourcePath $myctx $tempDestinationPathSiteAsset
        Write-Host "     >>>> file uploaded from:", $tempSourcePath, "- to:", $tempDestinationPathSiteAsset
        if($ExtranetSharing -eq "Disabled")
        {
            $tempPathBG =  -join($tempDestinationPathSiteAsset, "/", $ThemeFileIntranetBG)
        }
        else
        {
            $tempPathBG =  -join($tempDestinationPathSiteAsset, "/", $ThemeFileExtranetBG)
        }
       
         #Deploy Custom Color
        $tempSourcePath = -join($ThemeFileFolder, $ThemeFileSPColor)
        Upload-Specific-File  $tempSourcePath $myctx $tempDestinationPathSiteAsset
        Write-Host "     >>>> file uploaded from:", $tempSourcePath, "- to:", $tempDestinationPathSiteAsset
        $tempPathPalette =  -join($tempDestinationPathTheme, "/", $ThemeFileSPColor)
        if($RootOrSubstite -eq "RootSite")
        {
            Upload-Specific-File  $tempSourcePath $myctx $tempDestinationPathTheme
             Write-Host "     >>>> file uploaded from:", $tempSourcePath, "- to:", $tempDestinationPathTheme
            $tempPathPalette =  -join($tempDestinationPathTheme, "/", $ThemeFileSPColor)
         }
        else
        {
            $tempPathPalette =  -join($RootSiteRelativeURL, "/_catalogs/theme/15/", $ThemeFileSPColor)
        }
       
        #Deploy Custom Font
        $tempSourcePath = -join($ThemeFileFolder, $ThemeFileSPFont)
         Upload-Specific-File  $tempSourcePath $myctx $tempDestinationPathSiteAsset
        Write-Host "     >>>> file uploaded from:", $tempSourcePath, "- to:", $tempDestinationPathSiteAsset
        if($RootOrSubstite -eq "RootSite")
        {
            Upload-Specific-File  $tempSourcePath $myctx $tempDestinationPathTheme
            Write-Host "     >>>> file uploaded from:", $tempSourcePath, "- to:", $tempDestinationPathTheme
            $tempPathFont =  -join($tempDestinationPathTheme, "/", $ThemeFileSPFont)
        }
        else
        {
            $tempPathFont =  -join($RootSiteRelativeURL, "/_catalogs/theme/15/", $ThemeFileSPFont)
        }

        if($ExtranetSharing -eq "Disabled")
         {
            $masterPageUrl = -join($myCurrentWeb.ServerRelativeUrl, "/_catalogs/masterpage/", $IntranetMasterPage)
        }
        else
        {
            $masterPageUrl = -join($myCurrentWeb.ServerRelativeUrl, "/_catalogs/masterpage/", $ExtranetMasterPage)
        }
       
        Write-Host " ---------------------------------------------- "  -foregroundcolor green
         Write-Host "     ===>> tempPathPalette:", $tempPathPalette   -foregroundcolor green
        Write-Host "     ===>> tempPathFont:", $tempPathFont  -foregroundcolor green
        Write-Host "     ===>> tempPathBG:", $tempPathBG  -foregroundcolor green
        Write-Host "     ===>> masterPageUrl:", $masterPageUrl  -foregroundcolor green
        Write-Host " ---------------------------------------------- "  -foregroundcolor green

        $themesOverviewList = $myCurrentWeb.GetCatalog(124);
        $myctx.Load($themesOverviewList);
        $myctx.ExecuteQuery();

        $IDThemeCorp = IfThemeExists -Myctx $myctx -list $themesOverviewList -themeName $ThemeName
        if ($IDThemeCorp -eq 0)
         {
            # Create new theme entry.
            $itemInfo  = New-Object Microsoft.SharePoint.Client.ListItemCreationInformation
            $item = $themesOverviewList.AddItem($itemInfo)
            $item["Name"] = $ThemeName;
            $item["Title"] = $ThemeName;
            $item["ThemeUrl"] = $tempPathPalette;
            $item["FontSchemeUrl"] = $tempPathFont;
             $item["ImageUrl"] = $tempPathBG;
            $item["MasterPageUrl"] = $MasterPageUrl ;
            $item["DisplayOrder"] = 1;
            $item.Update()
            $myctx.ExecuteQuery();
        }
        else
        {
            [Microsoft.SharePoint.Client.ListItem]$listItem = $themesOverviewList.GetItemById($IDThemeCorp)
            $listItem["Name"] = $ThemeName;
             $listItem["Title"] = $ThemeName;
            $listItem["ThemeUrl"] = $tempPathPalette;
            $listItem["FontSchemeUrl"] = $tempPathFont;
            $listItem["ImageUrl"] = $tempPathBG;
            $listItem["MasterPageUrl"] = $MasterPageUrl ;
            $listItem["DisplayOrder"] = 1;
            $listItem.Update()
            $myctx.ExecuteQuery()       
        }
    }
    Catch [Exception]
    {
        Write-host " >>>> ERROR MESSAGE:", $_.Exception.Message -f Red
    }
}

function Get-SPOSubWebs
{
    Param(
        [Microsoft.SharePoint.Client.ClientContext]$Context,
        [Microsoft.SharePoint.Client.Web]$RootWeb,
        [string]$RootSiteRelURL,
        [string]$ExtranetMode
    )
   
    $Webs = $RootWeb.Webs
    $Context.Load($Webs)
    $Context.ExecuteQuery()
    ForEach ($sWeb in $Webs)
    {
        Write-host "   ====>> SubSite:", $sWeb.URL -ForegroundColor red
        AddNewCorpThemeInSPweb $Context $sWeb "subsite" $RootSiteRelURL $ExtranetMode

        Get-SPOSubWebs -RootWeb $sWeb -Context $Context -RootSiteRelURL $RootSiteRelURL $ExtranetMode
    }
}

cls
Write-Host " ---------------------------------------------- "
Load-DLLandAssemblies
Write-Host " ---------------------------------------------- "

Connect-SPOService -Url https://tenant-admin.sharepoint.com -credential $adminCreds -ErrorAction SilentlyContinue -ErrorVariable Err

#Retrieve all site collection infos
#Get-SPOSite -Template GROUP#0 #(Group Sites)
#Get-SPOSite -Template POINTPUBLISHINGTOPIC#0  #(Video Portal Sites)
#$sitesInfo = Get-SPOSite -Identity 
https://tenant.sharepoint.com/sites/testsitecoll  | Sort-Object -Property url | Select *
#$sitesInfo = Get-SPOSite -Template "STS#0" -Limit ALL | Sort-Object -Property url | Select *

$sitesInfo = Get-SPOSite -Template "STS#0" -Filter  {Url -like "https://tenant.sharepoint.com/sites/a*"}  -Limit ALL | Sort-Object -Property url | Select *

[int]$i = 1;
[string]$ExternalSharingSetting = ""

Write-Host "--------------------------------------------------------------------------------------------"
#Retrieve and print all sites
foreach ($site in $sitesInfo)
{
    $ExportAllUserLogin = ""
    Write-Host "SiteColl Number:", $i, "- of:", $sitesInfo.Count;
    $i += 1;
   
    Write-Host "--------------------------------------------------------------------------------------------"
    Write-Host "SPO Site collection:", $site.Url, "- Title:", $site.Title
    Write-Host "   => External Sharing:", $site.SharingCapability
    Write-Host "   => Site Template Used:", $site.Template
    Write-Host "   => Storage Quota:", $site.StorageQuota, "- Storage used:", $site.StorageUsageCurrent
    Write-Host "   => Percent Usage:", $($site.StorageUsageCurrent / $site.StorageQuota * 100), "%"
    Write-Host "   => Resource Quota:", $site.ResourceQuota, "- Resource used:", $site.ResourceUsageCurrent
    Write-Host "--------------------------------------------------------------------------------------------"

    #Set-SPOsite -Identity $site.Url -DenyAddAndCustomizePages 0 #Non mandatory but could be useful for the group sites

    $mySitectx = New-Object Microsoft.SharePoint.Client.ClientContext($site.Url)
    $mySitectx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($adminCreds.UserName, $adminCreds.Password)
    $mySitectx.RequestTimeout = 1000000 # milliseconds
    $myCurrentWeb = $mySitectx.Web
    $mySitectx.Load($myCurrentWeb)
    $mySitectx.ExecuteQuery()

    $ExternalSharingSetting = $site.SharingCapability

    AddNewCorpThemeInSPweb $mySitectx $myCurrentWeb "RootSite" $myCurrentWeb.ServerRelativeUrl $ExternalSharingSetting
    Get-SPOSubWebs $mySitectx $myCurrentWeb $myCurrentWeb.ServerRelativeUrl $ExternalSharingSetting
}

Write-Host " ---------------------------------------------- "

Les sites de référence sont les suivant:

Cette solution peut aussi être intégré dans vos script de provisioning permettant la création de Group ou Teams Office 365
 
Fabrice Romelard

Commentaires

Posts les plus consultés de ce blog

Série de vidéos sur le montage d'une serre horticole ACD

 Episode 1: Préparation du terrain Episode 2: Montage de la serre en elle même Episode 3: Finalisation avec le montage électrique alimentant la serre Bon visionnage Fab

Présentation des outils utiles pour l'entretien de ses haies vives

Afin de gérer les haies vives, il est nécessaire d'avoir recourt à un matériel adapté. Les solutions à batteries sont bien adaptées pour un usage personnel avec des dimensions raisonnables. Ainsi dans mon cas précis, j'utilise les outils suivants de la Gamme Ryobi 18V ONE+ électroportatif: Petit taille-haies simple mais efficace -  RYOBI OHT1855R Un modèle plus puissant qui fonctionne très bien -  RYOBI RY18HTX60A Pour les parties hautes de vos haies, voici un outil très utile -  RYOBI OPT1845 Enfin lorsque vous devez élaguer certains arbres ou certaines partie hautes de vos haies, ce dernier outil est très utile -  RYOBI OPP1820 Ces outils font parti maintenant de mon arsenal de base pour maintenir notre maison chaque saison de taille. Fab

Série de Videos sur Home Assistant intégrant la production Photovoltaïque

 Un certain nombre de vidéos sont en ligne pour intégrer sa production photovoltaïque dans Home Assistant en partant de la base. Installation de Home Assistant: On peut ensuite intégrer les composant des Micro-Onduleurs Enphase, mais aussi les batteries Enphase: Ou encore le composant de contrôle Ecojoko: Ce qui permet alors de faire des comparaisons entre les valeurs capturées: Des videos seront encore publiés dans les prochaines semaines sur différents aspects de cette solution. Fab