Script to set the banner in SharePoint Modern pages

Posted 25 July 2018 12:00 AM by Cristian Zaragoza, SharePoint Development Team Lead @ ClearPeople

SharePoint Modern pages allow users to customise the look and feel by adding a banner image at the top of the page. This is an often task that usually users do manually, but what happens if we're creating a lot of pages in different environments, such as Development QA, UAT and Live? In my case, I usually need to create SharePoint environments with default data from scratch.

Do we need to manually set the banner image on each page for each environment? Thanks to PowerShell, no we don't. We can run a PowerShell scripts that reads the information of each page, i.e: what image goes in what page, and then sets that image automatically. Obviously we should have created the pages and uploaded the images in a previous step. We can do this with another PowerShell script which we will talk about soon in another post.

So, with all of this in mind, the first step as said, is to create the Modern pages in SharePoint, and upload the images to some assets library. Then, we need to identify somehow, what banner image goes in what page. For this, I have the following dictionary:

$banners = @{"Welcome.aspx" = "home.png"; 
                         "Employee Images.aspx" = "employee-images.png"; 
                         "Publications.aspx" = "publications.png";
                         "Event Materials.aspx" = "event-materials.png";
                         "Advertisements.aspx" = "advertisements.png";
                         "Visual Guidelines.aspx" = "visual-guidelines.png";
                         "Stock Images.aspx" = "stock-images.png";
                         "Templates.aspx" = "templates.png";
                         "Contact.aspx" = "contact.png";
                         "Imprint.aspx" = "imprint.png";
                         "Cart.aspx" = "basket.png";
                        "Account.aspx" = "account.png";             

As you can see, basically I'm matching each Modern page with an image. In my case I have a separate script file (banners.ps1) with the banners information in a dictionary-way, so I can have as many environments as I need, and I just need to reference the proper banners.ps1 script from the main script as we'll see later. You can have that dictionary embedded in the script if you prefer it. I also have a "secrets" file (secrets.ps1) that contains the tenant and login details:

$properties = @{};
$properties.O365Tenant = "mytenant";
$properties.SPSite = "/sites/mysitename";
$properties.AppsCatalog = "/sites/myappcatalog";
$properties.UserName = "";
$properties.Password = 'xxxxxxxxxx';
$secrets = New-Object -TypeName PSObject -Property  $properties;

And finally, here you have the PowerShell script that will set the banner image on each Modern page, as per the information in the banners.ps1 and the tenant and login details from the secrets.ps1.

param ([string]$env = "dev", [string]$images = "Pictures", [string]$pages = "SitePages");

# Run secrets
$secretsScript =  (Split-Path $MyInvocation.MyCommand.Definition) + ("\\\\\\\\\\\\\\\\", $env, "\\\\\\\\\\\\\\\\" -join "") + "secrets.ps1";
. $secretsScript;

#Run banners
$bannersScript =  (Split-Path $MyInvocation.MyCommand.Definition) + ("\\\\\\\\\\\\\\\\", $env, "\\\\\\\\\\\\\\\\" -join "") + "banners.ps1";
. $bannersScript;

# Getting context
$credentials = new-object -typename System.Management.Automation.PSCredential -argumentlist $secrets.UserName, ($secrets.Password | ConvertTo-SecureString -AsPlainText -Force)
$webUrl = "https://{0}{1}/" -f $secrets.O365Tenant, $secrets.SPSite;
Write-Host "[1] Connecting to " -NoNewline
Write-Host $("{0}  " -f $webUrl) -NoNewline -ForegroundColor Yellow;
Connect-PnPOnline -url $webUrl -Credential $credentials;
$guidSite = (Get-PnPSite -Includes ID).ID.ToString();
$guidWeb = (Get-PnPWeb).ID.ToString();
Write-Host "OK!" -ForegroundColor Green;

#Getting pages
Write-Host "[2] Getting Client Side (Modern) Pages from " -NoNewline
Write-Host $("{0} " -f $pages) -NoNewline -ForegroundColor Yellow;
Write-Host "library..." -NoNewline;
$clientSidePages = (Get-PnPListItem -List $pages -Fields ID,Title,UniqueId,FileLeafRef) | %{new-object PSObject -Property @{Id=$_["ID"];UniqueId=$_["UniqueId"];FileLeafRef=$_["FileLeafRef"]; Title=[uri]::EscapeUriString($_["Title"]);}};
Write-Host "OK!" -ForegroundColor Green;

#Getting banners
Write-Host "[3] Getting banner images from " -NoNewline
Write-Host $("{0} " -f $images) -NoNewline -ForegroundColor Yellow;
Write-Host "library..." -NoNewline;
$bannerImages = (Get-PnPListItem -List $images -Fields ID,UniqueId,FileLeafRef,FileRef) | %{new-object PSObject -Property @{Id=$_["ID"];UniqueId=$_["UniqueId"];FileLeafRef=$_["FileLeafRef"];FileRef=$_["FileRef"]}};
$guidList = (Get-PnPList -Identity $images).ID.ToString();
Write-Host "OK!" -ForegroundColor Green;

Write-Host "[4] Setting banners:"
$counter = 1;
$banners.Keys | ForEach-Object {
    $pageKey = $_;
    $bannerValue = $banners[$pageKey];    
    Write-Host $("    [{0}/{1}] {2}|{3}" -f $counter++, $banners.Keys.Count, $pageKey, $bannerValue) -NoNewline -ForegroundColor Yellow;
    $clientSidePage = $clientSidePages | ?{$_.FileLeafRef -eq $pageKey;}
    if ($clientSidePage -ne $null) {
        $bannerImage = $bannerImages | ?{$_.FileLeafRef -eq $bannerValue;}
        if ($bannerImage -ne $null) {            
                $BannerImageUrlValue =  $("https://{0}{1}&guidWeb={2}&guidFile={3}, https://{0}{1}&guidWeb={2}&guidFile={3}" -f $secrets.O365Tenant, $guidSite, $guidWeb, $bannerImage.UniqueId);
                $LayoutWebpartsContentValue = $("<div><div data-sp-controldata=""%7B%22id%22&#58;%22{0}%22,%22instanceId%22&#58;%22{0}%22,%22title%22&#58;%22Title%20Region%22,
%22translateX%22&#58;50,%22translateY%22&#58;50%7D%7D"" data-sp-canvascontrol="""">
</div></div>" -f "cbe7b0a9-3504-44dd-a3a3-0e5cacd07788", $bannerImage.FileRef, $clientSidePage.Title, $guidSite, $guidWeb, $guidList, $bannerImage.UniqueId);

                $oItem = Set-PnPListItem -List $pages -Id $clientSidePage.ID  -Values @{"BannerImageUrl" =$BannerImageUrlValue; "LayoutWebpartsContent"= $LayoutWebpartsContentValue} -EA SilentlyContinue -EV ProcessError;
                if ($ProcessError) {Write-Host "  ERROR!" -ForegroundColor Red; $ProcessError}
                else {Write-Host "  OK!" -ForegroundColor Green;}
        else {Write-Host "  ERROR: " -ForegroundColor Red -NoNewline; Write-Host $("""{0}"" picture not found in ""{1}"" library" -f $bannerValue, $images)}
    else {Write-Host "  ERROR: " -ForegroundColor Red -NoNewline; Write-Host $("""{0}"" page not found in ""{1}"" library" -f $pageKey, $pages)}

Write-Host "[5] Provisioning completed" -ForegroundColor Green

So, basically we are doing these steps:

  1. Run the secrets.ps1 script to get the tenant and login details.
  2. Run the banners.ps1 script to the matching between Modern pages and banner images.
  3. Getting the context with SharePoint according to the secrets.ps1 data.
  4. Retrieving the Modern pages according to the banners.ps1 data.
  5. Retrieving the banner images according to the banners.ps1 data. There is a configuration parameter to specify in which assets library we are storing the banner images.
  6. Finally, we iterate through each Modern page and set the properties "BannerImageUrl" and "LayoutsWebpartsContent" with the proper value and format.

And it does! I hope you find this useful and help you saving some time when building different SharePoint environments/tenants with default data.​


Add your comment





intranet Modern SharePoint teamwork employee engagement digital workspace SharePoint JavaScript Windows Azure Digital Transformation staff satisfaction productivity Microsoft Teams Office 365 Yammer cms content management system agile GDPR Microsoft Graph collaboration Microsoft sharepoint 2016 upgrade migration SharePoint Online 2016 Tech Trends Digital Disruption Context marketing marketing SharePoint 2010 SharePoint 2013 TFS Git security kentico Analytics jquery QA Quality Assurance testing content management websites Sitecore sitecore marketplace sitecore module cloud Microsoft Cloud Storage digital strategy technical consulting sitecore modules Experience database Sitecore 7 Sitecore 8 support account management customer experience Data Storage cms integration front end front end development prototype Cloud Storage StorSimple Front-end Development Layout SharePoint 2013 colour palette UI design website design log viewer sitecore cms website Azure big data business-critical sharepoint accessibility android apple chrome clear people clearpeople debug emulator ios mobile testing opera resize adobe desktop flash ie10 internet explorer 10 metro windows 8 bcsp Advanced System Reporter reporting framework ControlMode form control master page placeholder publishing console SharePoint 2007 SharePoint error search search results search values software testing testing scenario audit content information architecture retention schedules PowerShell QuickLaunch scripts SharePoint server 2010 business solutions metalogix replication replicator storagepoint stena technet UK Technet picture library slideshow web part RTM released to manufacturing caml caml query MOSS 2007 query infopath