Skip to content

Instantly share code, notes, and snippets.

@jcallaghan
Last active October 23, 2019 12:02
Show Gist options
  • Save jcallaghan/a75ab5a44f316d551d96a34f95f11c8e to your computer and use it in GitHub Desktop.
Save jcallaghan/a75ab5a44f316d551d96a34f95f11c8e to your computer and use it in GitHub Desktop.
See https://jcallaghan.com/2019/09/sharepoint-footer/ for more information. #Website
function Get-BearerToken() {
<#
.SYNOPSIS
Gets an access token.
.DESCRIPTION
This is a custom function that returns an access token.
Assumes Connect-PnpOnline has already been established.
#>
$token = Get-PnPAppAuthAccessToken
$headers = @{ Authorization=("Bearer $($token)") }
return $headers
}
function Enable-SPOFooter{
<#
.SYNOPSIS
Enables the footer in an SPO site.
.DESCRIPTION
This is a custom function that enables the footer in a modern SPO site.
Assumes Connect-PnpOnline has already been established.
#>
Begin {
Write-Debug "Enable-SPOFooter function called."
$site = Get-PnPSite
Write-Debug "- Identity: $($site.url)"
}
Process {
$web = Get-PnPWeb
$web.FooterEnabled = $true
$web.Update()
Invoke-PnPQuery
}
End {
Write-Debug "- Footer enabled."
Write-Debug "Enable-SPOFooter finished."
}
}
function Disable-SPOFooter{
<#
.SYNOPSIS
Disables the footer in an SPO site.
.DESCRIPTION
This is a custom function that disables the footer in a modern SPO site.
Assumes Connect-PnpOnline has already been established.
#>
Begin {
Write-Debug "Disable-SPOFooter function called."
$site = Get-PnPSite
Write-Debug "- Identity: $($site.url)"
}
Process {
$web = Get-PnPWeb
$web.FooterEnabled = $false
$web.Update()
Invoke-PnPQuery
}
End {
Write-Debug "- Footer disabled."
Write-Debug "Disable-SPOFooter finished."
}
}
function Get-SPOFooter{
<#
.SYNOPSIS
Gets the configuration of the footer in an SPO site.
.DESCRIPTION
This is a custom function that sets the text the footer in a modern SPO site.
Assumes Connect-PnpOnline has already been established.
Requires Get-BearerToken, Get-SPOFooterText, Get-SPOFooterLogo functions.
#>
Begin {
Write-Debug "Get-SPOFooter function called."
$site = Get-PnPSite
Write-Debug "- Identity: $($site.url)"
}
Process {
# Call MenuState and work through JSON to see if the footer is enabled or not.
$headers = Get-BearerToken
$api = "$($site.url)/_api/navigation/MenuState?menuNodeKey='13b7c916-4fea-4bb2-8994-5cf274aeb530'"
$nav = Invoke-WebRequest $api -Method Get -Headers $headers -ContentType 'application/json'
[xml]$xmlNav = $nav.Content
# If there is no menustate property the footer is not enabled.
if($xmlNav.MenuState.null -eq "true"){
Write-Debug "- Footer not enabled."
$footerEnabled = $false
}else{
$footerEnabled = $true
}
# Build collection to return how the footer is configured.
$footerInfo = New-Object PSObject -Property @{
Enabled = $footerEnabled
Text = Get-SPOFooterText
Logo = Get-SPOFooterLogo
#Links = ""
}
}
End {
Write-Debug "Get-SPOFooter finished."
return $footerInfo | Select-Object Enabled, Text, Logo | Format-List
}
}
function Set-SPOFooter{
<#
.SYNOPSIS
Sets the footer configuration in an SPO site.
.DESCRIPTION
This is a custom function that augments the other functions in this script.
It helps set the configuration for the footer in a modern SPO site.
Assumes Connect-PnpOnline has already been established.
Requires Get-BearerToken function.
.PARAMETER Enabled
Enables/disables the footer.
.PARAMETER FooterText
Specifies the text that should be set in the footer.
.PARAMETER FooterLogoUrl
Specifies the logo url that should be set in the footer.
.EXAMPLE
PS C:\>Set-SPOFooter -Enabled:$true -FooterText "Contoso. Copyright 2019." -FooterLogoUrl /sites/news/siteassets/footerlogo.png
#>
param(
[Parameter(Mandatory=$true)]
[boolean] $Enabled,
[Parameter(Mandatory=$true)]
[string] $FooterText,
[Parameter(Mandatory=$true)]
[string] $FooterLogoUrl
)
Begin {
Write-Debug "Set-SPOFooter function called."
$site = Get-PnPSite
Write-Debug "- Identity: $($site.url)"
Write-Debug "- Enabled: $($Enabled)"
Write-Debug "- Footer text: $($FooterText)"
Write-Debug "- Footer logo: $($FooterLogoUrl)"
}
Process{
# Enable/disable footer
if($Enabled -eq $true){
Enable-SPOFooter
}elseif($Enabled -eq $false){
Disable-SPOFooter
}
# Set footer text
if($null -ne $FooterText){
Set-SPOFooterText -FooterText $FooterText
}
# Set footer logo
if($null -ne $FooterLogoUrl){
Set-SPOFooterLogo -FooterLogoUrl $FooterLogoUrl
}
}
End{
Write-Debug "Set-SPOFooter finished."
}
}
function Set-SPOFooterText{
<#
.SYNOPSIS
Sets the footer text in an SPO site.
.DESCRIPTION
This is a custom function that sets the text the footer in a modern SPO site.
Assumes Connect-PnpOnline has already been established.
Requires Get-BearerToken function.
.PARAMETER FooterText
Specifies the text that should be set in the footer.
.EXAMPLE
PS C:\>Set-SPOFooterText -FooterText "Contoso. Copyright 2019."
#>
param(
[Parameter(Mandatory=$true)]
[string] $FooterText
)
Begin {
Write-Debug "Set-SPOFooterText function called."
$site = Get-PnPSite
Write-Debug "- Identity: $($site.url)"
Write-Debug "- Footer text: $($FooterText)"
}
Process {
# Enable the footer
$web = Get-PnPWeb
$web.FooterEnabled = $true
$web.Update()
Invoke-PnPQuery
# Post JSON to the SaveMenuState API to set the footer text.
$headers = Get-BearerToken
$body = '{"menuState":{"StartingNodeTitle":"13b7c916-4fea-4bb2-8994-5cf274aeb530","SPSitePrefix":"/","SPWebPrefix":"' + $($web.ServerRelativeUrl) + '","FriendlyUrlPrefix":"","SimpleUrl":"","Nodes":[{"NodeType":0,"Title":"7376cd83-67ac-4753-b156-6a7b3fa0fc1f","Key":"2004","FriendlyUrlSegment":"","Nodes":[{"NodeType":0,"Title":"' + $($footerText) + '","FriendlyUrlSegment":""}]}]}}'
$api = "$($site.url)/_api/navigation/SaveMenuState"
try{
$response = Invoke-WebRequest $api -Method Post -Body $body -Headers $headers -ContentType 'application/json'
}catch{
Write-Error "- API call failed. "
}
}
End {
if($response.StatusCode -eq 200){
Write-Debug "- Footer text successfully applied."
}else{
Write-Debug $response
}
Write-Debug "Set-SPOFooterText finished."
}
}
function Get-SPOFooterText{
<#
.SYNOPSIS
Gets the footer text in an SPO site.
.DESCRIPTION
This is a custom function that gets the text the footer in a modern SPO site.
Assumes Connect-PnpOnline has already been established.
Requires Get-BearerToken function.
#>
Begin {
Write-Debug "Get-SPOFooterText function called."
$site = Get-PnPSite
Write-Debug "- Identity: $($site.url)"
}
Process {
# Call the MenuState API and work through the JSON and get node that contains the title.
$headers = Get-BearerToken
$api = "$($site.url)/_api/navigation/MenuState?menuNodeKey='13b7c916-4fea-4bb2-8994-5cf274aeb530'"
try{
$response = Invoke-WebRequest $api -Method Get -Headers $headers -ContentType 'application/json'
[xml]$xmlNav = $response.Content
$node = $xmlNav.MenuState.Nodes.ChildNodes | Where-Object {$_.Title -eq "7376cd83-67ac-4753-b156-6a7b3fa0fc1f"}
$footerText = $node.Nodes.element.Title
Write-Debug "- Footer JSON: Node:$($node.Key); Title:$($node.Nodes.element.Title);"
}catch{
Write-Error "- API call failed. "
}
}
End {
if($response.StatusCode -eq 200){
Write-Debug "- Footer text: $($footerText)"
$return = $footerText
}else{
$return = $response
}
Write-Debug "Get-SPOFooterText finished."
return $return
}
}
function Set-SPOFooterLogo{
<#
.SYNOPSIS
Sets the footer logo in an SPO site.
.DESCRIPTION
This is a custom function that sets the logo in the footer in a modern SPO site.
Assumes Connect-PnpOnline has already been established.
Requires Get-BearerToken function.
.PARAMETER FooterText
Specifies the footer logo that should be set in the footer.
.EXAMPLE
PS C:\>Set-SPOFooterLogo -FooterLogoUrl ""
#>
param(
[Parameter(Mandatory=$true)]
[string] $FooterLogoUrl
)
Begin {
Write-Debug "Set-SPOFooterLogo function called."
$site = Get-PnPSite
Write-Debug "- Identity: $($site.url)"
Write-Debug "- Footer logo url: $($FooterLogoUrl)"
}
Process {
$web = Get-PnPWeb
$web.FooterEnabled = $true
$web.Update()
Invoke-PnPQuery
# Post JSON to the SaveMenuState API to set the footer logo.
$headers = Get-BearerToken
$body = '{"menuState":{"StartingNodeTitle":"13b7c916-4fea-4bb2-8994-5cf274aeb530","SPSitePrefix":"/","SPWebPrefix":"' + $($web.ServerRelativeUrl) + '","FriendlyUrlPrefix":"","SimpleUrl":"","Nodes":[{"NodeType":0,"Title":"2e456c2e-3ded-4a6c-a9ea-f7ac4c1b5100","Key":"2006","SimpleUrl":"' + $($FooterLogoUrl) + '","FriendlyUrlSegment":""}]}}'
$api = "$($site.Url)/_api/navigation/SaveMenuState"
try{
$response = Invoke-WebRequest $api -Method Post -Body $body -Headers $headers -ContentType 'application/json'
}catch{
Write-Debug "- API call failed."
}
}
End {
if($response.StatusCode -eq 200){
Write-Debug "- Footer text successfully applied."
}else{
Write-Debug $response
}
Write-Debug "Set-SPOFooterLogo finished."
}
}
function Get-SPOFooterLogo{
<#
.SYNOPSIS
Gets the footer logo set in an SPO site.
.DESCRIPTION
This is a custom function that gets the logo from the footer in a modern SPO site.
Assumes Connect-PnpOnline has already been established.
Requires Get-BearerToken function.
#>
Begin {
Write-Debug "Get-SPOFooterLogo function called."
$site = Get-PnPSite
Write-Debug "- Identity: $($site.url)"
}
Process {
# Call the MenuState API and work through the JSON and get node that contains the title.
$headers = Get-BearerToken
$api = "$($site.url)/_api/navigation/MenuState?menuNodeKey='13b7c916-4fea-4bb2-8994-5cf274aeb530'"
try{
$response = Invoke-WebRequest $api -Method Get -Headers $headers -ContentType 'application/json'
[xml]$xmlNav = $response.Content
$node = $xmlNav.MenuState.Nodes.ChildNodes | Where-Object {$_.Title -eq "2e456c2e-3ded-4a6c-a9ea-f7ac4c1b5100"}
$footerLogo = $node.SimpleUrl
}catch{
Write-Error "- API call failed. "
}
}
End {
if($response.StatusCode -eq 200){
Write-Debug "- Footer logo: $($footerLogo)"
$return = $footerLogo
}else{
$return = $response
}
Write-Debug "Get-SPOFooterLogo finished."
return $return
}
}
function Set-SPOFooterLinks{
param(
[string]$identity
)
Write-Debug "Set-SPOFooterCustomerLinks function called."
Write-Debug "Identity: $($identity)"
try{
$connection = Connect-PnPOnline -url $identity -AppId $clientId -AppSecret $secret -ReturnConnection
}catch{
Write-Error "Cannot connect to site."
}
try{
$web = Get-PnPWeb -Connection $connection
$web.FooterEnabled = $true
$web.Update()
Invoke-PnPQuery
}catch{
Write-Error "Footer cannot be enabled."
}
$headers = Get-BearerToken
$api = "$($identity)/_api/navigation/MenuState?menuNodeKey='13b7c916-4fea-4bb2-8994-5cf274aeb530'"
$nav = Invoke-WebRequest $api -Method Get -Headers $headers -ContentType 'application/json'
[xml]$xmlNav = $nav
$node = $xmlNav.MenuState.Nodes.ChildNodes | Where-Object {$_.Title -eq "3a94b35f-030b-468e-80e3-b75ee84ae0ad"}
$nav = $node.SimpleUrl
if($null -ne $node){
$purgeNode = $node.Key
$body = '{"menuState":{"StartingNodeTitle":"3a94b35f-030b-468e-80e3-b75ee84ae0ad","SPSitePrefix":"/","SPWebPrefix":"' + $($web.ServerRelativeUrl) + '","FriendlyUrlPrefix":"","SimpleUrl":"","Nodes":[{"NodeType":0,"Key":"' + $purgeNode + '","Title":"","SimpleUrl":"","FriendlyUrlSegment":"","IsDeleted":"true"}]}}'
$api = "$($identity)/_api/navigation/SaveMenuState"
try{
$response = Invoke-WebRequest $api -Method Post -Body $body -Headers $headers -ContentType 'application/json'
}catch{
Write-Debug "API call failed."
}
}
$api = "$($identity)/_api/navigation/SaveMenuState"
<# Nav sample
"Nodes":[
{"NodeType":0,"Title":"Help","SimpleUrl":"/sites/Help","FriendlyUrlSegment":"","IsDeleted":false},
{"NodeType":0,"Title":"Acceptable Use Policy","SimpleUrl":"/sites/help/sitepages/Acceptable-Use-Policy.aspx","FriendlyUrlSegment":"","IsDeleted":false},
{"NodeType":0,"Title":"Accessibility","SimpleUrl":"/sites/Help/sitepages/Accessibility.aspx","FriendlyUrlSegment":""},
{"NodeType":0,"Title":"Send us you feedback","SimpleUrl":"/sites/Help/sitepages/DiploHub-Feedback.aspx","FriendlyUrlSegment":""}
]}}'
#>
$body = '{"menuState":{"StartingNodeTitle":"3a94b35f-030b-468e-80e3-b75ee84ae0ad","SPSitePrefix":"/","SPWebPrefix":"' + $($web.ServerRelativeUrl) + '","FriendlyUrlPrefix":"","SimpleUrl":"","Nodes":[{"NodeType":0,"Title":"Help","SimpleUrl":"/sites/Help","FriendlyUrlSegment":"","IsDeleted":false},{"NodeType":0,"Title":"Acceptable Use Policy","SimpleUrl":"/sites/help/sitepages/Acceptable-Use-Policy.aspx","FriendlyUrlSegment":"","IsDeleted":false},{"NodeType":0,"Title":"Accessibility","SimpleUrl":"/sites/Help/sitepages/Accessibility.aspx","FriendlyUrlSegment":""},{"NodeType":0,"Title":"Send us you feedback","SimpleUrl":"/sites/Help/sitepages/DiploHub-Feedback.aspx","FriendlyUrlSegment":""}]}}'
try{
$response = Invoke-WebRequest $api -Method Post -Body $body -Headers $headers -ContentType 'application/json'
}catch{
Write-Debug "API call failed."
}
Disconnect-PnPOnline -Connection $connection
return $response.StatusCode
}
$DebugPreference = "Continue" #SilentlyContinue; Continue;
$clientId = "[clientId]"
$secret = "[secret]";
$siteUrl = "[tenant]/sites/News"
Connect-PnPOnline -url $siteUrl -AppId $clientId -AppSecret $secret
# Get the configuration of the footer
#Get-SPOFooter
# Set the footer rather than needing to use the separate functions
#Set-SPOFooter -Enabled:$true -FooterText "ABC" -FooterLogoUrl "/sites/news/siteassets/footerlogo.png"
# Enable and disable the footer
#Enable-SPOFooter
#Disable-SPOFooter
# Get the footer text
#Get-SPOFooterText
# Set the footer text
#Set-SPOFooterText -FooterText "Whitehall. Copyright 2019. ABC."
# Get the footer logo
#Get-SPOFooterLogo
# Footer logo assumes logo has already been uploaded. You can use the following to upload a logo to the site assets library.
<#
$web = Get-PnpWeb
$logoUrl = "$($web.ServerRelativeUrl)/SiteAssets/footerlogo.png"
Enable-PnPFeature -Identity 00bfea71-d8fe-4fec-8dad-01c19a6e4053
Add-PnPFile -Path ".\footerlogo.png" -Folder "SiteAssets"
try{
$logo = Get-PnPFile -url $logoUrl
}catch{
Write-Debug "Logo not found."
}
#>
# Set footer logo
#Set-SPOFooterLogo -FooterLogoUrl "/sites/news/siteassets/footerlogo.png"
# Set footer links
#Set-SPOFooterLinks -identity $siteUrl
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment